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;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值