HDU 3699(J) ——A hard Aoshu Problem(DFS暴力搜索)

来源:互联网 发布:怎么修改tomcat的端口 编辑:程序博客网 时间:2024/06/08 08:43

题目连接:点击打开链接

题目大意:输入三个字符串,s1, s2, s3,每个字符串只含有大写英文字母组成,并且每个英文字母代表一个特定的数字,然后求 s1 _ s2  =  s3; 有多少种解法

注意数字无前导零,然后分母不为0, 第一组测试样例: 1 * 1 = 1; 1 / 1 = 1 ; 0 + 0 = 0 ; 0 - 0 = 0 ; 0 * 0 = 0;

解题思路:因为每个串的长度不超过8,并且这三个串中最多不超过5个字符,所以可以用暴力列举所有的可能的数字情况,然后再进行判断整理

暴力枚举运用DFS进行,很巧妙,有生成全排列(A)的方法,不知道有没有生成随机自由组合(C)的方法;

代码:

//HDU 3699暴力搜索#include<iostream>#include<cstdio>#include<cstring>#include<map>using namespace std;map<char, int> mp, dl; //数字对应, 位置对应char s1[10], s2[10], s3[10];char s[30];int ans;int flag[10];int vis[100];int l;void cal(){    int a = 0, b = 0, c = 0;    for(int i = 0; i < strlen(s1); i++)        a = a * 10 + mp[s1[i]];    for(int i = 0; i < strlen(s2); i++)        b = b * 10 + mp[s2[i]];    for(int i = 0; i < strlen(s3); i++)        c = c * 10 + mp[s3[i]];    if(a + b == c) ans++;    if(a * b == c) ans++;    if(a - b == c) ans++;    if(b && a == b*c) ans++; //b不为0, 并且a = b * c}//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!void dfs(int num){    if(num == l)//当num达到l长度的时候,就开始计算,也就是全部分配完的时候开始计算    {        cal();        return ;    }    for(int i = 0; i < 10; i++) //9个数字中选择    {        if(i == 0 && dl[s[num]] == 1) continue; //保证首位不为0        if(flag[i] == 0)        {            flag[i] = 1; //保证在每一次循环里的排列数字是不重复的,            mp[s[num]] = i;            dfs(num+1);            flag[i] = 0; //随机排列,相当于每一次用完之后在进行清零初始化处理        }    }}//********************************************************************************int main(){    int T;    scanf("%d", &T);    while(T--)    {        ans = 0;        memset(vis, 0, sizeof(vis));        memset(flag, 0, sizeof(flag));        mp.clear(); dl.clear();        ans = 0;        scanf("%s %s %s", s1, s2, s3);        if(strlen(s1) > 1) dl[s1[0]] = 1;        if(strlen(s2) > 1) dl[s2[0]] = 1;        if(strlen(s3) > 1) dl[s3[0]] = 1; //三个字符串首字母所对应的位置都为1        l = 0;        for(int i = 0; i < strlen(s1); i++)        {            if(vis[s1[i]-'A'] != 0) continue;            vis[s1[i]-'A'] = 1;            s[l++] = s1[i];        }        for(int i = 0; i < strlen(s2); i++)        {            if(vis[s2[i]-'A'] != 0) continue;            vis[s2[i]-'A'] = 1;            s[l++] = s2[i];        }        for(int i = 0; i < strlen(s3); i++)        {            if(vis[s3[i]-'A'] != 0) continue;            vis[s3[i]-'A'] = 1;            s[l++] = s3[i];        }        dfs(0);        printf("%d\n", ans);    }    return 0;}



原创粉丝点击