/* Problem Description 速算24点相信绝大多数人都玩过。就是随机给你四张牌,包括A(1),2,3,4,5,6,7,8,9,10,J(11),Q(12),K(13)。要求只用'+','-','*','/'运算符以及括号改变运算顺序,使得最终运算结果为24(每个数必须且仅能用一次)。游戏很简单,但遇到无解的情况往往让人很郁闷。你的任务就是针对每一组随机产生的四张牌,判断是否有解。我们另外规定,整个计算过程中都不能出现小数。 Input 每组输入数据占一行,给定四张牌。 Output 每一组输入数据对应一行输出。如果有解则输出"Yes",无解则输出"No"。 Sample Input A 2 3 6 3 3 8 8 Sample Output Yes No Author LL Source ACM暑期集训队练习赛(三) Recommend linle | We have carefully selected several similar problems for you: 1430 1428 1426 1422 1429 */ #include<stdio.h> #include<algorithm> #include<stdlib.h> #include<string.h> #define INF 0x3f3f3f3f using namespace std; char s[4]; int num[4]; int get(char *c) { if(c[0] == 'A') return 1; else if( c[0] >= '2' && c[0] <= '9') return c[0] - '0'; else if( c[0] == 'J') return 11; else if( c[0] == 'Q') return 12; else if( c[0] == 'K') return 13; else return 10; } int cmp(const void * a, const void * b) { return *(int *)a - *(int *)b; } int cal2(int x, int op, int y) { if(op == 0) return x+y; else if(op == 1) return x-y; else if(op == 2) return x*y; else if(y && x % y == 0) return x/y; return INF; } bool cal(int x, int y, int z) { int ans , temp ; temp = cal2(num[0], x, num[1]); ans = temp; temp = cal2(num[2], z, num[3]); if(ans != INF && temp != INF) { ans = cal2(ans, y, temp); if(ans == 24 || ans == -24) return true; } ans = INF; temp = cal2(num[0], x, num[1]); if(temp != INF) ans = cal2(temp, y, num[2]); if(ans != INF) ans = cal2(ans, z, num[3]); if(ans == 24 || ans == -24) return true; return false; } int main() { int i, j, k, count = 0; while(scanf("%s", s) != EOF) { num[count++] = get(s); for(i = 0; i < 3; ++i) { scanf("%s", s); num[count++] = get(s); } count = 0; qsort(num, 4, sizeof(num[0]), cmp); bool ok = false; do{ for(i = 0; i < 4 && !ok; ++i) for(j = 0; j < 4 && !ok; ++j) for(k = 0; k < 4 && !ok; ++k) ok = cal(i, j, k); }while(!ok && next_permutation(num, num+4)); if(ok) printf("Yes\n"); else printf("No\n"); } return 0; } //题意:很直白,玩过的都知道 //思路:大牛总结规律,就2种情况(a op b)op (c op d) 或者 (((a op b) op c) op d) //用全排列暴力abcd,然后暴力运算符