24点

· · 个人记录

二十四点

计算二十四点是一个传统游戏,本题目是二十四点的弱化版,在正式的课程中要求的是中间变量可以输出小数,不过并不影响本题的思路,只需要设定一个精度精度来判断是否去等即可。
考察一个二十四点,一共只有四个数,三个符号。因此数字的顺序可以全排列,每一个符号也可以考虑枚举的操作。对于加括号,我们可以采用另一种思路完成这个操作:运算符只有三个,因此其运算顺序只有六种,我们可以枚举运算顺序从而完成加括号的操作。
注意一点,我们可以避免负数解对输出带来的不便。因为出线负数解时,我们一定可以通过某种方式将负数转变为正数。因此,每当出现负数的时候我们直接跳过即可。

#include<bits/stdc++.h>
using namespace std;

int a[5];

int C(int A,int B,int f)
{
    if(f == 1)return A + B;
    if(f == 2)return A - B;
    if(f == 3)return A * B;
    if(B == 0 || A % B != 0)return 10000;
    if(f == 4 && B)return A / B;
}

int re1,re2,re3;

char gf(int x)
{
    if(x == 1)return '+';
    if(x == 2)return '-';
    if(x == 3)return '*';
    if(x == 4)return '/';
}

void pr(int x11,int x12,int f1,int x21,int x22,int f2,int x31,int x32,int f3)
{
    if(re1 < 0 || re2 < 0 || re3 < 0)return;
    if(f1 == 1 || f1 == 3)if(x11 < x12)swap(x11,x12);
    if(f2 == 1 || f2 == 3)if(x21 < x22)swap(x21,x22);
    if(f3 == 1 || f3 == 3)if(x31 < x32)swap(x31,x32);
    cout  << x11 << gf(f1) << x12 << '=' << re1 << endl;
    cout  << x21 << gf(f2) << x22 << '=' << re2 << endl;
    cout  << x31 << gf(f3) << x32 << '=' << re3 << endl;
    exit(0);
}

void calc(int f1,int f2,int f3)
{

    //1,2,3
    re1 = C(a[1],a[2],f1);
    re2 = C(re1,a[3],f2);
    re3 = C(re2,a[4],f3);
    if(re1 != 10000 && re2 != 10000 && re3 == 24)
    {
        pr(a[1],a[2],f1,re1,a[3],f2,re2,a[4],f3);
    }
    //1,3,2
    re1 = C(a[1],a[2],f1);
    re2 = C(a[3],a[4],f3);
    re3 = C(re1,re2,f2);
    if(re1 != 10000 && re2 != 10000 && re3 == 24)
    {
        pr(a[1],a[2],f1,a[3],a[4],f3,re1,re2,f2);
    }
    //2,1,3
    re1 = C(a[2],a[3],f2);
    re2 = C(a[1],re1,f1);
    re3 = C(re2,a[4],f3);
    if(re1 != 10000 && re2 != 10000 && re3 == 24)
    {
        pr(a[2],a[3],f2,a[1],re1,f1,re2,a[4],f3);
    }
    //2,3,1
    re1 = C(a[2],a[3],f2);
    re2 = C(re1,a[4],f3);
    re3 = C(a[1],re2,f1);
    if(re1 != 10000 && re2 != 10000 && re3 == 24)
    {
        pr(a[2],a[3],f2,re1,a[4],f3,a[1],re2,f1);
    }
    //3,1,2
    re1 = C(a[3],a[4],f3);
    re2 = C(a[1],a[2],f1);
    re3 = C(re2,re1,f2);
    if(re1 != 10000 && re2 != 10000 && re3 == 24)
    {
        pr(a[3],a[4],f3,a[1],a[2],f1,re2,re1,f2);
    }
    //3,2,1
    re1 = C(a[3],a[4],f3);
    re2 = C(a[2],re1,f2);
    re3 = C(a[1],re2,f1);
    if(re1 != 10000 && re2 != 10000 && re3 == 24)
    {
        pr(a[3],a[4],f3,a[2],re1,f2,a[1],re2,f1);
    }
}

void check()
{
    for(int i = 1; i <= 4; i++)
    {
        for(int j = 1; j <= 4; j++)
        {
            for(int k = 1; k <= 4; k++)
            {
                calc(i,j,k);
            }
        }
    }
}

int main()
{
    for(int i = 1; i <= 4; i++) cin >> a[i];
    sort(a + 1,a + 5);
    check();
    while(next_permutation(a + 1,a + 5))
    {
        check();
    }
    cout << "No answer!";
    return 0;
}