HNU11374:GREAT+SWERC=PORTO(DFS)

Problem description

We want to have a great SWERC at Porto this year and we approached this challenge in several ways. We even framed it as a word addition problem, similar to the classic SEND+MORE=MONEY, where each letter stands for a single digit (0, 1, 2, ..., 8, 9) that makes the arithmetic operation correct. In word additions different letters cannot be assigned the same digit and the leftmost letter in a word cannot be zero (0). In particular, a single letter term cannot be zero.

Given a word addition problem, compute the number of solutions (possibly zero).


Input

A line with an integer n, followed by n lines containing a word each with maximum length of 10 letters. The first n-1 words are the terms to be added and the last line is the result.
Words contain only capital letters. If words have different lengths, they must be interpreted as aligning to the right. For instance, in the SEND+MORE=MONEY problem, the D of the first word and E of the second word align with the Y of the final word. You can also assume that the size of the last word is greater than or equal to the maximum size of the preceding words, and moreover, at most ten distinct letters are involved in a word problem.
3<=n<=10 Each word has at most 10 symbols (capital letters). A word problem has at most 10 distinct letters.


Output

A single line with an integer: the number of solutions of the word addition problem given as input.


Sample Input
3
GREAT
SWERC
PORTO
3
SEND
MORE
MONEY
5
TOO
GOOD
TO
BE
TRUE
Sample Output
6
1
93
Problem Source
HNU Contest 


题意:

给出你一个字母组成的加法式子,在右对齐之后,前n-1个相加得到第n个字符串,要求你对每个字母赋值0~9,每个字母代表的数字不能一样,且没有前导0,有几种赋值方法


思路:

直接对于每个字母分别尝试不同的赋值,搜索下去


#include <iostream>
#include <stdio.h>
#include <string.h>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <math.h>
#include <bitset>
#include <algorithm>
#include <climits>
using namespace std;

#define ls 2*i
#define rs 2*i+1
#define UP(i,x,y) for(i=x;i<=y;i++)
#define DOWN(i,x,y) for(i=x;i>=y;i--)
#define MEM(a,x) memset(a,x,sizeof(a))
#define W(a) while(a)
#define gcd(a,b) __gcd(a,b)
#define LL long long
#define N 20005
#define INF 0x3f3f3f3f
#define EXP 1e-8
#define rank rank1
const int mod = 1000000007;

int n,letter[20],cot,len[20],hsh[200],num[200],ans;
char str[20][20];

int check()
{
    int i,j,k;
    for(i = 0; i<n; i++)//前导0不行
    {
        if(num[str[i][0]]==0)
            return 0;
    }
    int jin = 0;//进位
    for(j = 0; j<len[n-1]; j++)//从右边(个位)开始算
    {
        if(num[str[n-1][len[n-1]-1-j]]==-1) return 1;//这个字母没有被赋值,返回并往下搜
        int sum = jin;
        for(i = 0; i<n-1; i++)
        {
            if(len[i]-1-j<0) continue;
            if(num[str[i][len[i]-1-j]]==-1) return 1;//这个字母没有被赋值,返回并往下搜
            sum+=num[str[i][len[i]-1-j]];
        }
        if(sum%10!=num[str[n-1][len[n-1]-1-j]]) return 0;//对应位之和与最后一个不等
        jin=sum/10;
    }
    return !jin;//进位为0则解决了
}

void dfs(int cnt)
{
    int i;
    if(cnt==-1)
    {
        ans++;
        return;
    }
    for(i = 0; i<10; i++)//给字母尝试所有不同的赋值赋值
    {
        if(hsh[i]==0)
        {
            hsh[i] = 1;
            num[letter[cnt]] = i;
            if(check())//赋值可行则继续进行
                dfs(cnt-1);
            hsh[i] = 0;
            num[letter[cnt]] = -1;
        }
    }
}

int main()
{
    int i,j,k;
    while(~scanf("%d",&n))
    {
        MEM(hsh,0);
        cot = -1;
        for(i = 0; i<n; i++)
        {
            scanf("%s",str[i]);
            len[i] = strlen(str[i]);
            for(j = 0; j<len[i]; j++)
            {
                if(!hsh[str[i][j]])
                {
                    hsh[str[i][j]] = 1;
                    letter[++cot] = str[i][j];//记录所有字母
                }
            }
        }
        ans = 0;
        MEM(hsh,0);
        MEM(num,-1);
        dfs(cot);
        printf("%d\n",ans);
    }

    return 0;
}


题目:![图片说明](https://img-ask.csdn.net/upload/201805/26/1527317808_511212.png)![图片说明](https://img-ask.csdn.net/upload/201805/26/1527317825_834369.png) 问题:自己看了题解之后写了代码,可是还是出不来,不懂是哪里出错了,请大家指教!!!!!! 我的代码: ```#include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<algorithm> using namespace std; int len[20],letter[20],dex,n,i,j,ans,num[200],flag[200]; char str[20][20]; int check() { for(i = 0;i < n; i++) { if(num[str[i][0]] == 0) return 0; } int jin = 0; for(j = 0;j < len[n - 1]; j++) { if(num[str[n - 1][len[n - 1] - 1 - j]] == -1) return 1; int sum = jin; for(i = 0;i < n - 1; i++) { if(len[i] - 1 - j < 0) continue; if(num[str[i][len[i] - 1 - j]] == -1) return 1; sum += num[str[i][len[i] - 1 - j]]; } if(sum % 10 != num[str[n - 1][len[n - 1] - 1 - j]]) return 0; jin = sum / 10; } return !jin; } void dfs(int dex) { if(dex == -1) { ans++; return; } for(i = 0;i < 10; i++) { if(flag[i] == 0) { flag[i] = 1; num[letter[dex]] = i; if(check()) dfs(dex - 1); flag[i] = 0; num[letter[dex]] = -1; } } } int main() { while(scanf("%d",&n) != EOF) { dex = -1; memset(num,0,sizeof(num)); for(i = 0;i < n; i++) { scanf("%s",str[i]); len[i] = strlen(str[i]); for(j = 0;j < len[i]; j++) { if(!num[str[i][j]]) { num[str[i][j]] = 1; letter[++dex] = str[i][j]; } } } ans = 0; memset(num,-1,sizeof(num)); memset(flag,0,sizeof(flag)); dfs(dex); printf("%d\n",ans); } return 0; } ```
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页