【DFS】Ybt_虫食算

题目大意

可恶的虫子把一些数字吃掉了!
你只能知道数位数和进制数为n的三个数 A,B,C。
其中 C=A B,数字都由大写字母表示,相同字母表示这个位置上是相同的数字。
要你求每个字母所代表的数字。

输入

5
ABCED
BDACE
EBBAA

输出

1 0 3 4 2


深度搜索。枚举这些字母代表的数字。
从后往前枚举列,设这列的被加数,加数,与和为 a,b,c,得:

  1. 如果上一列的a’,b’确定,那么进位也是确定的,如果a b t不等于这一列的c,方案不合法
  2. 如果上一列不确定,如果 a b不等于c 且 a b 1不等于c,方案不合法
  3. 如果最大位有进位…方案不合法。

代码

#include<cstdio>#include<cstring>#include<iostream>using namespace std;bool used[30];int n, flag, t;int k[30],A[30],B[30],S[30],sssx[30];char getc(){  //读入char lc = getchar();while(lc > 'Z' || lc < 'A') lc = getchar();return lc;}bool check(){  //判断int jw = 0;for(int i = n; i > 0; --i){int a = k[A[i]], b = k[B[i]], c = k[S[i]];if(a != -1 && b != -1 && c != -1){ //知道这三个数if(jw != -1){  //知道进位if((a b jw) % n != c) return 0;if(i == 1 && a b jw >= n) return 0;  //最大位超jw = (a b jw) / n;} else{  //不知道进位if((a b) % n != c && (a b 1) % n !=c) return 0; if(i == 1 && a b >=n) return 0; //最大位超}}else jw = -1;}return 1;  //返回}void dfs(int noo){  //第几个该填的数的序号...if(noo == n){flag = 1;return;}int no = sssx[noo];  //no为该填的数for(int i = n-1; i >= 0; --i)  //倒着轮会快一点if(used[i] == 0){ //没填过    k[no] = i;if(check()){  //判断    used[i] = 1;    dfs(noo   1);    if(flag) return;    used[i] = 0;    }    k[no] = -1;}} int main(){scanf("%d", &n);for(int i = 1; i <= n;   i) A[i] = getc()-65;for(int i = 1; i <= n;   i) B[i] = getc()-65;for(int i = 1; i <= n;   i) S[i] = getc()-65;for(int i = n; i >= 1; --i){  //搞个判断字母的顺序(从数位小到大)if(used[A[i]] == 0) sssx[t  ] = A[i];used[A[i]] = 1;if(used[B[i]] == 0) sssx[t  ] = B[i];used[B[i]] = 1;if(used[S[i]] == 0) sssx[t  ] = S[i];used[S[i]] = 1;}memset(used, 0, sizeof(used));for(int i = 0; i < n;   i) k[i] = -1; dfs(0);for(int i = 0; i < n;   i) //输出  printf("%d ", k[i]);}

来源:https://www.icode9.com/content-4-815251.html

(0)

相关推荐