题目链接:A hard Aoshu Problem
DES:给三个字符串,包含的字符是A-E范围内的。长度都不超过8。每个字符可以而且只可以匹配一个数字。两个字符不能匹配相同的数字。前两个式子之间可以有+-*/四中关系。然后=第三个式子。问。会有多少种关系式。
#include<stdio.h> #include<string.h> #include<iostream> using namespace std; char s[3][10]; int a[10], b[10], c[10]; // 字符转换成数字后存储。 int num[6]; // 每个字符匹配给哪个数字。 int len[3]; int vis1[6], vis2[10]; //vis1[]保存下标对应字符是否出现。(A B C D E->0 1 2 3 4)。vis2[]标记枚举数字时标记是否已经出现过、 int ans; int aa, bb, cc; //三个字符串对应的数字、 int check() // 不可有前导0的检查。 { if (len[0] > 1 && num[a[0]] == 0) return 0; if (len[1] > 1 && num[b[0]] == 0) return 0; if (len[2] > 1 && num[c[0]] == 0) return 0; return 1; } void getnum() //根据每次枚举把三个字符串换成数字。 { aa = 0, bb = 0, cc = 0; for (int i=0; i<len[0]; ++i) { aa = aa * 10 + num[a[i]]; } for (int i=0; i<len[1]; ++i) { bb = bb * 10 + num[b[i]]; } for (int i=0; i<len[2]; ++i) { cc = cc * 10 + num[c[i]]; } } int gettot() //看有几种运算关系。 { int temp = 0; if (aa + bb == cc) temp++; if (aa - bb == cc) temp++; if (aa * bb == cc) temp++; if (bb * cc == aa && bb != 0) temp++; return temp; } void dfs(int x) // 暴力枚举每一个字符匹配十个数字的情况。 { if (x == 5) // x表示当前枚举第几个字母。如果枚举完就可以看当前匹配有几种关系式。 { if (check()) { getnum(); int cnt = gettot(); ans += cnt; return; } } else if (vis1[x]) // 如果x对应的字符出现在三个字符串里、 { for (int i=0; i<=9; ++i) // 开始枚举。 { if (vis2[i] == 0) { num[x] = i; vis2[i] = 1; dfs(x+1); vis2[i] = 0; // 回溯 } } } else dfs(x+1); // 否则就继续匹配下一个字符。 } int main() { int t; cin >> t; while(t--) { ans = 0; memset(vis1, 0, sizeof(vis1)); memset(vis2, 0, sizeof(vis2)); // 输入处理 for (int i=0; i<3; ++i) { cin >> s[i]; len[i] = strlen(s[i]); for (int j=0; j<len[i]; ++j) { int temp = s[i][j] - 'A'; if (i == 0) a[j] = temp; if (i == 1) b[j] = temp; if (i == 2) c[j] = temp; vis1[temp]++; } } dfs(0); cout << ans << endl; } return 0; }