虫食算
题目链接:ybt高效进阶1-4-3 \ luogu P1092
题目大意
一个 A+B=C 的 N 进制式子(三个数都是 N 进制的 N 位数),已知三个数的某些位上的数是相等的,别的就不相等。
问你你要怎么填才能使等式成立。
只有一种解。
思路
我们考虑从低位向高位不断确定填的数。
至于不确定的就每一个都试一遍,那其实就是 dfs。
然后为了缩短时间,我们每确定一个数就要把已经确定的式子和只是不知道进位的式子都看一遍,看是否合法。
已经确定的很简单,不知道进不进位的就两种情况都看(反正最多只能进
1
1
1,你是相加),要是都式子不成立就不行。
然后就按着这个方法 dfs,遇到解就输出,退出。
代码
#include<cstdio>
using namespace std;
int n, num[31], a[4][31];
bool use[31], yes;
char ch[31];
void write() {
for (int i = 1; i <= n; i++)
printf("%d ", num[i]);
}
void dfs(int now, int noww, int bu) {
if (!now && !bu) {
write();
yes = 1;
return ;
}
if (!now) {
return ;
}
for (int i = now - 1; i >= 1; i--)
if (num[a[1][i]] >= 0 && num[a[2][i]] >= 0 && num[a[3][i]] >= 0 && (num[a[1][i]] + num[a[2][i]]) % n != num[a[3][i]] && (num[a[1][i]] + num[a[2][i]] + 1) % n != num[a[3][i]])
//已经出现了确定一定不符合的式子
return ;
if (num[a[noww][now]] >= 0) {
if (noww == 3) {//如果这一列搞好了要看是否符合(下面也是一个道理)
if ((num[a[1][now]] + num[a[2][now]] + bu) % n != num[a[3][now]]) return ;
dfs(now - 1, 1, (num[a[1][now]] + num[a[2][now]] + bu) / n);
}
else dfs(now, noww + 1, bu);
}
else {
for (int i = 0; i < n; i++)
if (!use[i]) {
use[i] = 1;
num[a[noww][now]] = i;
if (noww == 3) {
if (!((num[a[1][now]] + num[a[2][now]] + bu) % n != num[a[3][now]]))
dfs(now - 1, 1, (num[a[1][now]] + num[a[2][now]] + bu) / n);
}
else dfs(now, noww + 1, bu);
num[a[noww][now]] = -1;
use[i] = 0;
}
}
}
int main() {
scanf("%d", &n);
for (int i = 1; i <= n; i++)
num[i] = num[i] = num[i] = -1;
scanf("%s", &ch);
for (int i = 0; i < n; i++)
a[1][i + 1] = ch[i] - 'A' + 1;
scanf("%s", &ch);
for (int i = 0; i < n; i++)
a[2][i + 1] = ch[i] - 'A' + 1;
scanf("%s", &ch);
for (int i = 0; i < n; i++)
a[3][i + 1] = ch[i] - 'A' + 1;
dfs(n, 1, 0);
return 0;
}