描述
判断输入四个数字能否计算出24,,需要考虑除0异常,浮点数操作。
输入
第1行:1个正整数, t,表示数据组数,2≤t≤100。
第2..t+1行:4个正整数, a,b,c,d,1≤a,b,c,d≤10。
输出
第1..t行:每行一个字符串,第i行表示第i组能否计算出24点。若能够输出"Yes",否则输出"No"。
2 5 5 5 1 9 9 9 9
Yes No
方案一:#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm> using namespace std; bool used[4]; int number[4]; int nowNumber[] = {0,0,0,0}; int ops[] = {0,0,0}; int opType[] = { 1,2,3,4,5,6 };//+,-,*,/,反-,反/ double calc(double a, double b, int ops) { switch (ops) { case 1:return a + b; break; case 2:return a - b; break; case 3:return a * b; break; case 4:if(b!=0) return a * 1.0 / b; break; case 5:return b - a; break; case 6:if(a!=0) return b * 1.0 / a; break; default:return 0; break; } return 0; } bool calcType1(int nowNumber[], int ops[]) { //计算在(((a ⊙ b) ⊙ c) ⊙ d) double tmp = nowNumber[0]; for (int i = 0; i < 3; ++i) tmp = calc(tmp, nowNumber[i + 1], ops[i]); if (abs(tmp - 24)<0.000001) return true; else return false; } bool calcType2(int nowNumber[], int ops[]) { //计算在((a ⊙ b) ⊙ (c ⊙ d)) double a = calc(nowNumber[0], nowNumber[1], ops[0]); double b = calc(nowNumber[2], nowNumber[3], ops[2]); double tmp = calc(a, b, ops[1]); if (abs(tmp-24)<0.000001) return true; else return false; } bool makeOperation(int depth) { if (depth >= 3) { //枚举完三个操作符 if (calcType1(nowNumber, ops)) return true; if (calcType2(nowNumber, ops)) return true; return false; } for (int i = 0; i < 6; ++i) { ops[depth] = opType[i]; if (makeOperation(depth + 1)) return true; } return false; } bool makeNumber(int depth) { if (depth >= 4) { //枚举完四个操作数 return makeOperation(0); } for (int i = 0; i < 4; ++i) { if (!used[i]) { nowNumber[depth] = number[i]; used[i] = true; if (makeNumber(depth + 1)) return true; used[i] = false; } } return false; } int main() { int t; cin >> t; while (t--) { cin >> number[0] >> number[1] >> number[2] >> number[3]; memset(used, false, sizeof(used)); if (makeNumber(0)) cout << "Yes" << endl; else cout << "No" << endl; } return 0; }
方案二:考虑重复数字,减少枚举次数
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm> using namespace std; int number[4]; int ops[] = { 0,0,0 }; int opType[] = { 1,2,3,4,5,6 };//+,-,*,/,反-,反/ bool flag = false; double calc(double a, double b, int ops) { switch (ops) { case 1:return a + b; break; case 2:return a - b; break; case 3:return a * b; break; case 4:if (b != 0) return a * 1.0 / b; break; case 5:return b - a; break; case 6:if (a != 0) return b * 1.0 / a; break; default:return 0; break; } return 0; } bool calcType1(int nowNumber[], int ops[]) { //计算在(((a ⊙ b) ⊙ c) ⊙ d) double tmp = nowNumber[0]; for (int i = 0; i < 3; ++i) tmp = calc(tmp, nowNumber[i + 1], ops[i]); if (abs(tmp - 24)<0.000001) return true; else return false; } bool calcType2(int nowNumber[], int ops[]) { //计算在((a ⊙ b) ⊙ (c ⊙ d)) double a = calc(nowNumber[0], nowNumber[1], ops[0]); double b = calc(nowNumber[2], nowNumber[3], ops[2]); double tmp = calc(a, b, ops[1]); if (abs(tmp - 24)<0.000001) return true; else return false; } void makeOperation(int depth) { if (depth >= 3) { //枚举完三个操作符 if (calcType1(number, ops)) { flag = true; return; } if (calcType2(number, ops)) { flag = true; return; } return; } for (int i = 0; i < 6; ++i) { ops[depth] = opType[i]; makeOperation(depth + 1); } } int main() { int t; cin >> t; while (t--) { cin >> number[0] >> number[1] >> number[2] >> number[3]; sort(number, number + 4); flag = false; do { makeOperation(0); if (flag) break; } while (next_permutation(number, number + 4)); if (flag) cout << "Yes" << endl; else cout << "No" << endl; } return 0; }