速算24点
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 3226 Accepted Submission(s): 775
Problem Description
速算24点相信绝大多数人都玩过。就是随机给你四张牌,包含A(1),2,3,4,5,6,7,8,9,10,J(11),Q(12),K(13)。要求仅仅用'+','-','*','/'运算符以及括号改变运算顺序,使得终于运算结果为24(每一个数必须且仅能用一次)。游戏非常easy,但遇到无解的情况往往让人非常郁闷。你的任务就是针对每一组随机产生的四张牌,推断是否有解。我们另外规定,整个计算过程中都不能出现小数。
Input
每组输入数据占一行,给定四张牌。
Output
每一组输入数据相应一行输出。假设有解则输出"Yes",无解则输出"No"。
Sample Input
A 2 3 6 3 3 8 8
Sample Output
Yes No
算法分析:
首先进行全排列,之后进行深搜,注意括号仅仅有两种情况(a@b)@(c@d)和((a@b)@c)@d.
#include<iostream> #include<algorithm> using namespace std; int res[4]; void dfs(int sum, int cur, int temp); bool flag = 0; int main() { char s[3]; int i,j,k; while(1) { for(i = 0;i < 4;i ++) { if(scanf("%s",s) == EOF) return 0; if(s[0] == 'A') res[i] = 1; else if(s[0] == 'J') res[i] = 11; else if(s[0] == 'Q') res[i] = 12; else if(s[0] == 'K') res[i] = 13; else if(s[0] == '1' && s[1] == '0') res[i] = 10; else res[i] = s[0] - '0'; } sort(res, res+4); flag = 0; do { dfs(res[0], 1, res[1]); }while(next_permutation(res, res+4)&&!flag); if(flag) printf("Yes "); else printf("No "); } return 0; } void dfs(int sum, int cur, int temp) { if(flag) return; if(cur==3) { if(sum+temp==24) flag=1; if(sum-temp==24) flag=1; if(sum*temp==24) flag=1; if(temp!=0&&sum%temp==0&&sum/temp==24) flag=1; return; } dfs(sum+temp, cur+1, res[cur+1]); dfs(sum-temp, cur+1, res[cur+1]); dfs(sum*temp, cur+1, res[cur+1]); if(temp!=0&&sum%temp==0) dfs(sum/temp, cur+1, res[cur+1]); dfs(sum, cur+1, temp+res[cur+1]); dfs(sum, cur+1, temp-res[cur+1]); dfs(sum, cur+1, temp*res[cur+1]); if(res[cur+1]!=0&&temp%res[cur+1]==0) dfs(sum, cur+1, temp/res[cur+1]); }还有一种解法,
#include <stdio.h> #include <string.h> int a[10]; int map[10]; int flag = 1; int get(char *str) { if(str[0] == 'A') return 1; if(str[0] == '1') return 10; if(str[0] == 'J') return 11; if(str[0] == 'Q') return 12; if(str[0] == 'K') return 13; return str[0] - '0'; } void DFS(int s1,int s2,int k,int x)//(A@B)@(C@D) { int i; if(k == 4) { if(x == 1) { if(s1 == 24 || s1 == -24) { flag = 1; } } else { if(s1 + s2 == 24 || s1 + s2 == -24 || s1 - s2 == 24 || s1 - s2 == -24 || s1 * s2 == 24 || s1 * s2 == -24) flag = 1; if(s2 && s1 % s2 == 0 && s1 /s2 == 24) { flag = 1; } } return ; } for(i = 1;i <= 4; i++) { if(!map[i]) { map[i] = 1; if(k == 0) { DFS(a[i],s2,k+1,1); } else if(k == 1) { DFS(s1+a[i],s2,k+1,1); DFS(s1-a[i],s2,k+1,1); DFS(s1*a[i],s2,k+1,1); if(a[i] && s1 % a[i] == 0) DFS(s1/a[i],s2,k+1,1); } else { if(k == 2) { DFS(s1+a[i],s2,k+1,1); DFS(s1-a[i],s2,k+1,1); DFS(s1*a[i],s2,k+1,1); if(a[i] && s1 % a[i] == 0) DFS(s1/a[i],s2,k+1,1); DFS(s1,a[i],k+1,2); } else { if(x == 1) { DFS(s1+a[i],s2,k+1,1); DFS(s1-a[i],s2,k+1,1); DFS(s1*a[i],s2,k+1,1); if(a[i] && s1 % a[i] == 0) DFS(s1/a[i],s2,k+1,1); } else { DFS(s1,s2+a[i],k+1,2); DFS(s1,s2-a[i],k+1,2); DFS(s1,s2*a[i],k+1,2); if(a[i] && s2 % a[i] == 0) DFS(s1,s2 / a[i],k+1,2); } } } map[i] = 0; } } } int main() { char str[12]; int i; while(scanf("%s",str)!=EOF) { flag = 0; a[1] = get(str); for(i = 2;i <= 4;i++) { scanf("%s",str); a[i] = get(str); } memset(map,0,sizeof(map)); DFS(0,0,0,1); if(flag) printf("Yes "); else printf("No "); } return 0; }
关于next_permutation函数在C++(迭代訪问)与C(下标訪问)中的使用方法的使用,函数类型返回值是bool类型。
C++:
#include <iostream> #include <algorithm> #include <string> using namespace std; int main() { string str; cin >> str; sort(str.begin(), str.end()); cout << str << endl; while (next_permutation(str.begin(), str.end())) { cout << str << endl; } return 0; }C:
#include <cstdio> #include <algorithm> #include <cstring> #define MAX 100 using namespace std; int main() { int length; char str[MAX]; gets(str); length = strlen(str); sort(str, str + length); puts(str); while (next_permutation(str, str + length)) { puts(str); } return 0; }