Twenty Four, Again

题目描述

Yes, we know . . . we’ve used Challenge 24 before for contest problems. In case you’ve never heard of Challenge 24 (or have a very short memory) the object of the game is to take 4 given numbers (the base values) and determine if there is a way to produce the value 24 from them using the four basic arithmetic operations (and parentheses if needed). For example, given the four base values 3 5 5 2, you can produce 24 in many ways. Two of them are: 5*5-3+2 and (3+5)*(5-2). Recall that multiplication and division have precedence over addition and subtraction, and that equal-precedence operators are evaluated left-to-right. 

This is all very familiar to most of you, but what you probably don’t know is that you can grade the quality of the expressions used to produce 24. In fact, we’re sure you don’t know this since we’ve just made it up. Here’s how it works: A perfect grade for an expression is 0. Each use of parentheses adds one point to the grade. Furthermore, each inversion (that is, a swap of two adjacent values) of the original ordering of the four base values adds two points. The first expression above has a grade of 4, since two inversions are used to move the 3 to the third position. The second expression has a better grade of 2 since it uses no inversions but two sets of parentheses. As a further example, the initial set of four base values 3 6 2 3 could produce an expression of grade 3 — namely (3+6+3)*2 — but it also has a perfect grade 0 expression — namely 3*6+2*3. Needless to say, the lower the grade the “better” the expression.

Two additional rules we’ll use: 1) you cannot use unary minus in any expression, so you can’t take the base values 3 5 5 2 and produce the expression -3+5*5+2, and 2) division can only be used if the result is an integer, so you can’t take the base values 2 3 4 9 and produce the expression 2/3*4*9. 

Given a sequence of base values, determine the lowest graded expression resulting in the value 24. And by the way, the initial set of base values 3 5 5 2 has a grade 1 expression — can you find it?

 

输入

Input consists of a single line containing 4 base values. All base values are between 1 and 100, inclusive.

 

输出

Display the lowest grade possible using the sequence of base values. If it is not possible to produce 24,display impossible.

 

样例输入

3 5 5 2

 

样例输出

1
#include<bits/stdc++.h>
using namespace std;
int a[4],na[4];
int pos[][4]=
{
    {0,1,2,3},{0,1,3,2},{0,2,1,3},{0,2,3,1},{0,3,1,2},{0,3,2,1},
    {1,0,2,3},{1,0,3,2},{1,2,0,3},{1,2,3,0},{1,3,0,2},{1,3,2,0},
    {2,0,1,3},{2,0,3,1},{2,1,0,3},{2,1,3,0},{2,3,0,1},{2,3,1,0},
    {3,0,1,2},{3,0,2,1},{3,1,0,2},{3,1,2,0},{3,2,0,1},{3,2,1,0}
};//24种可能的位置
int poscost[]= {0,1,1,2,2,3,1,2,2,3,3,4,2,3,3,4,4,5,3,4,4,5,5,6};//位置对应的交换次数
struct node
{
    int num,lson,rson;
} ns[100];
void init()//五组表达式树的结构
{
    ns[1].lson=2;
    ns[1].rson=3;
    ns[2].lson=4;
    ns[2].rson=5;
    ns[3].lson=6;
    ns[3].rson=7;//第一组
    ns[8].lson=9;
    ns[8].rson=10;
    ns[9].lson=11;
    ns[9].rson=12;
    ns[11].lson=13;
    ns[11].rson=14;//第二组
    ns[15].lson=16;
    ns[15].rson=17;
    ns[16].lson=18;
    ns[16].rson=19;
    ns[19].lson=20;
    ns[19].rson=21;//第三组
    ns[22].lson=23;
    ns[22].rson=24;
    ns[24].lson=25;
    ns[24].rson=26;
    ns[25].lson=27;
    ns[25].rson=28;//第四组
    ns[29].lson=30;
    ns[29].rson=31;
    ns[31].lson=32;
    ns[31].rson=33;
    ns[33].lson=34;
    ns[33].rson=35;//第五组
}
void tree(int rt,int i,int& idx,int &op)
{
    if(ns[rt].lson==0&&ns[rt].rson==0)
    {
        ns[rt].num=a[pos[i][idx++]];
        return;
    }
    tree(ns[rt].lson,i,idx,op);
    ns[rt].num=-(op%4)*1000-1000;
    op/=4;
    tree(ns[rt].rson,i,idx,op);
}
int calc(int rt,int& cost)
{
    if(ns[rt].lson==0&&ns[rt].rson==0)
    {
        return ns[rt].num;
    }
    if(ns[rt].num==-3000||ns[rt].num==-4000)
    {
        if(ns[ns[rt].lson].num==-1000||ns[ns[rt].lson].num==-2000)
        {
            cost++;
        }
        if(ns[ns[rt].rson].num==-1000||ns[ns[rt].rson].num==-2000)
        {
            cost++;
        }
    }
    int l=calc(ns[rt].lson,cost);
    int r=calc(ns[rt].rson,cost);
    if(l==-1000||r==-1000)
    {
        return -1000;
    }
    switch(ns[rt].num)
    {
    case -1000:
        return l+r;
    case -2000:
        return l-r;
    case -3000:
        return l*r;
    case -4000:
        if(r==0||l%r!=0)
        {
            return -1000;
        }
        return l/r;
    }
}
int minn=1000;
int main()
{
    init();
    for(int i=0;i<4;i++)
    {
        scanf("%d",&a[i]);
    }
    for(int i=0;i<5;i++)//枚举括号
    {
        for(int j=0;j<24;j++)//枚举位置
        {
            for(int k=0;k<64;k++)//枚举运算符
            {
                int idx=0,op=k,cost=2*poscost[j];//代价初始化为交换后的代价
                tree(i*7+1,j,idx,op);
                int ans=calc(i*7+1,cost);
                if(ans==24)
                {
                    minn=min(minn,cost);
                }
            }
        }
    }
    if(minn==1000)
    {
        printf("impossible\n");
    }
    else
    {
        printf("%d\n",minn);
    }
    return 0;
}

 

上一篇:mac os x绝对时间与时钟时间之间转换


下一篇:linux工作利器之一,dns解析工具dig