UVALive 5107 dfs暴力搜索

时间:2023-03-08 16:28:18

题目链接:A hard Aoshu Problem

DES:给三个字符串,包含的字符是A-E范围内的。长度都不超过8。每个字符可以而且只可以匹配一个数字。两个字符不能匹配相同的数字。前两个式子之间可以有+-*/四中关系。然后=第三个式子。问。会有多少种关系式。

#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std; char s[][];
int a[], b[], c[]; // 字符转换成数字后存储。
int num[]; // 每个字符匹配给哪个数字。
int len[];
int vis1[], vis2[]; //vis1[]保存下标对应字符是否出现。(A B C D E->0 1 2 3 4)。vis2[]标记枚举数字时标记是否已经出现过、
int ans;
int aa, bb, cc; //三个字符串对应的数字、 int check() // 不可有前导0的检查。
{
if (len[] > && num[a[]] == ) return ;
if (len[] > && num[b[]] == ) return ;
if (len[] > && num[c[]] == ) return ;
return ;
} void getnum() //根据每次枚举把三个字符串换成数字。
{
aa = , bb = , cc = ;
for (int i=; i<len[]; ++i)
{
aa = aa * + num[a[i]];
}
for (int i=; i<len[]; ++i)
{
bb = bb * + num[b[i]];
}
for (int i=; i<len[]; ++i)
{
cc = cc * + num[c[i]];
}
} int gettot() //看有几种运算关系。
{
int temp = ;
if (aa + bb == cc) temp++;
if (aa - bb == cc) temp++;
if (aa * bb == cc) temp++;
if (bb * cc == aa && bb != ) temp++;
return temp;
} void dfs(int x) // 暴力枚举每一个字符匹配十个数字的情况。
{
if (x == ) // x表示当前枚举第几个字母。如果枚举完就可以看当前匹配有几种关系式。
{
if (check())
{
getnum();
int cnt = gettot();
ans += cnt;
return;
}
} else if (vis1[x]) // 如果x对应的字符出现在三个字符串里、
{
for (int i=; i<=; ++i) // 开始枚举。
{
if (vis2[i] == )
{
num[x] = i;
vis2[i] = ;
dfs(x+);
vis2[i] = ; // 回溯
}
}
}
else dfs(x+); // 否则就继续匹配下一个字符。
} int main()
{
int t;
cin >> t;
while(t--)
{
ans = ;
memset(vis1, , sizeof(vis1));
memset(vis2, , sizeof(vis2));
// 输入处理
for (int i=; i<; ++i)
{
cin >> s[i];
len[i] = strlen(s[i]);
for (int j=; j<len[i]; ++j)
{
int temp = s[i][j] - 'A';
if (i == ) a[j] = temp;
if (i == ) b[j] = temp;
if (i == ) c[j] = temp;
vis1[temp]++;
}
}
dfs();
cout << ans << endl;
}
return ;
}