【DFS】Ybt_虫食算
作者:互联网
题目大意
可恶的虫子把一些数字吃掉了!
你只能知道数位数和进制数为n的三个数 A,B,C。
其中 C=A+B,数字都由大写字母表示,相同字母表示这个位置上是相同的数字。
要你求每个字母所代表的数字。
输入
5
ABCED
BDACE
EBBAA
输出
1 0 3 4 2
解
深度搜索。枚举这些字母代表的数字。
从后往前枚举列,设这列的被加数,加数,与和为 a,b,c,得:
- 如果上一列的a’,b’确定,那么进位也是确定的,如果a+b+t不等于这一列的c,方案不合法
- 如果上一列不确定,如果 a+b不等于c 且 a+b+1不等于c,方案不合法
- 如果最大位有进位…方案不合法。
代码
#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]);
}
标签:used,return,食算,jw,Ybt,DFS,int,30,sssx 来源: https://blog.csdn.net/qq_42937087/article/details/112393825