题目:给你五个数字,在他们中间加上‘+‘,‘-‘,‘*‘,构成结果23,问能否成功。
分析:搜索,24点类似物。
首先,求出五个数的全排列;
然后,按顺序枚举三种运算,计算结果,判断即可。
说明:注意优先级,左边的高。
#include <iostream> #include <cstdlib> #include <cstdio> using namespace std; int data[5],save[5],used[5],buf[5]; int P[120][5]; int p_count; //生成全排列 void makep(int d) { if (d == 5) { for (int i = 0 ; i < 5 ; ++ i) P[p_count][i] = save[i]; p_count ++; return; } for (int i = 0 ; i < 5 ; ++ i) if (!used[i]) { used[i] = 1; save[d] = i; makep( d+1 ); used[i] = 0; } } //计算24点类似物 bool flag; void dfs(int d) { if (flag) return; if (!d) { if (buf[0] == 23) flag = 1; return; } //储存状态 int temp[5],a,b; for (int i = 0 ; i <= d ; ++ i) temp[i] = buf[i]; a = buf[0]; b = buf[1]; for (int i = 1 ; i < d ; ++ i) buf[i] = buf[i+1]; buf[0] = a+b; dfs(d-1); buf[0] = a-b; dfs(d-1); buf[0] = a*b; dfs(d-1); //回溯 for (int i = 0 ; i <= d ; ++ i) buf[i] = temp[i]; } int main() { p_count = 0; makep(0); while (~scanf("")) { for (int i = 0 ; i < 5 ; ++ i) scanf("%d",&data[i]); if (data[0] == 0) break; flag = 0; for (int i = 0 ; i < 120 ; ++ i) { for (int j = 0 ; j < 5 ; ++ j) buf[j] = data[P[i][j]]; dfs(4); if (flag) break; } if (flag) printf("Possible\n"); else printf("Impossible\n"); } return 0; }
测试数据:
输入:
42 8 2 32 37 10 43 21 46 5 44 2 27 30 29 10 20 20 2 36 28 3 34 42 2 22 6 6 5 37 34 3 31 18 12 25 46 28 13 2 12 4 19 2 50 1 12 2 1 49 48 48 42 2 11 1 2 43 26 33 0 0 0 0 0输出:
Possible Possible Impossible Impossible Impossible Impossible Impossible Impossible Impossible Impossible Impossible Impossible
原文:http://blog.csdn.net/mobius_strip/article/details/38852239