https://www.luogu.org/problem/P1092
题目描述
所谓虫食算,就是原先的算式中有一部分被虫子啃掉了,需要我们根据剩下的数字来判定被啃掉的字母。来看一个简单的例子:
43#9865#045
+ 8468#6633
44445509678
其中#号代表被虫子啃掉的数字。根据算式,我们很容易判断:第一行的两个数字分别是5和3,第二行的数字是5。
现在,我们对问题做两个限制:
首先,我们只考虑加法的虫食算。这里的加法是N进制加法,算式中三个数都有N位,允许有前导的0。
其次,虫子把所有的数都啃光了,我们只知道哪些数字是相同的,我们将相同的数字用相同的字母表示,不同的数字用不同的字母表示。如果这个算式是N进制的,我们就取英文字母表午的前N个大写字母来表示这个算式中的0到N−1这N个不同的数字:但是这N个字母并不一定顺序地代表0到N−1。输入数据保证N个字母分别至少出现一次。
BADC
+CBDA
DCCC
上面的算式是一个4进制的算式。很显然,我们只要让ABCD分别代表0123,便可以让这个式子成立了。你的任务是,对于给定的N进制加法算式,求出N个不同的字母分别代表的数字,使得该加法算式成立。输入数据保证有且仅有一组解。
输入格式
包含四行。
第一行有一个正整数N(N≤26)。
后面的三行,每行有一个由大写字母组成的字符串,分别代表两个加数以及和。这3个字符串左右两端都没有空格,从高位到低位,并且恰好有N位。
输出格式
一行,即唯一的那组解。
解是这样表示的:输出N个数字,分别表示A,B,C,…所代表的数字,相邻的两个数字用一个空格隔开,不能有多余的空格。
输入输出样例
输入 #1
5
ABCED
BDACE
EBBAA
输出 #1
1 0 3 4 2
说明/提示
对于30%的数据,保证有N≤10;
对于50%的数据,保证有N≤15;
对于全部的数据,保证有N≤26。
代码
#include<algorithm>
#include<iostream>
#include<string.h>
#include<stdio.h>
using namespace std;
int i,n;
char ch,gl[2],a[27],b[27],c[27];
int ans[27];
bool used[27];
void read()
{
scanf("%d",&n);
gets(gl);
for (i=n; i>=1; i--)
scanf("%c",&a[i]);
gets(gl);
for (i=n; i>=1; i--)
scanf("%c",&b[i]);
gets(gl);
for (i=n; i>=1; i--)
scanf("%c",&c[i]);
}
void update(int k, int which, int value)
{
used[value]=1;
if (which==1) ans[a[k]-'A']=value;
if (which==2) ans[b[k]-'A']=value;
if (which==3) ans[c[k]-'A']=value;
}
void goback(int k, int which, int value)
{
used[value]=0;
if (which==1) ans[a[k]-'A']=-1;
if (which==2) ans[b[k]-'A']=-1;
if (which==3) ans[c[k]-'A']=-1;
}
int judge1(int k, int jw, int &newjz, int &which, int &value)
{
int cnt=0;
if (ans[a[k]-'A']>=0) cnt++;
if (ans[b[k]-'A']>=0) cnt++;
if (ans[c[k]-'A']>=0) cnt++;
if (cnt<2) return -1;
if (cnt==3){
if ((ans[a[k]-'A']+ans[b[k]-'A']+jw)%n!=ans[c[k]-'A'])
return 0;
newjz=(ans[a[k]-'A']+ans[b[k]-'A']+jw)/n;
return 1;
}
if (ans[c[k]-'A']<0)
{
int tmp=ans[a[k]-'A']+ans[b[k]-'A']+jw;
if (used[tmp%n]) return 0;
newjz=tmp/n;
which=3; value=tmp%n;
return 1;
}
if (ans[a[k]-'A']<0)
{
int tmp=ans[c[k]-'A']-ans[b[k]-'A']-jw,tmp1=(tmp+n)%n;
if (used[tmp1]) return 0;
newjz=tmp1!=tmp;
which=1; value=tmp1;
return 1;
}
if (ans[b[k]-'A']<0)
{
int tmp=ans[c[k]-'A']-ans[a[k]-'A']-jw,tmp1=(tmp+n)%n;
if (used[tmp1]) return 0;
newjz=tmp1!=tmp;
which=2; value=tmp1;
return 1;
}
}
bool judge2(int k)
{
int cnt=0;
if (ans[a[k]-'A']>=0) cnt++;
if (ans[b[k]-'A']>=0) cnt++;
if (ans[c[k]-'A']>=0) cnt++;
if (cnt<2) return 1;
if (cnt==3)
{
int tmp=ans[a[k]-'A']+ans[b[k]-'A'];
if (tmp%n!=ans[c[k]-'A'] && (tmp+1)%n!=ans[c[k]-'A']) return 0;
return 1;
}
if (ans[c[k]-'A']<0)
{
int tmp=(ans[a[k]-'A']+ans[b[k]-'A'])%n;
if (used[tmp]&&used[(tmp+1)%n]) return 0;
return 1;
}
if (ans[a[k]-'A']<0)
{
int tmp=(ans[c[k]-'A']-ans[b[k]-'A']+n)%n;
if (used[tmp]&&used[(tmp-1+n)%n]) return 0;
return 1;
}
if (ans[b[k]-'A']<0)
{
int tmp=(ans[c[k]-'A']-ans[a[k]-'A']+n)%n;
if (used[tmp]&&used[(tmp-1+n)%n]) return 0;
return 1;
}
}
void dfs(int k, int jw)
{
if (k>n){
for (int i=0; i<n-1; i++)
printf("%d ",ans[i]);
printf("%d",ans[n-1]);
exit(0);
}
for (int i=k; i<=n; i++)
if (judge2(i)==0) return;
if (ans[a[n]-'A']+ans[b[n]-'A']>=n) return;
int newjz,which=0,value=-1;
int tmp1=judge1(k,jw,newjz,which,value);
if (tmp1==0) return;
if (tmp1==1)
{
if (which==0)
dfs(k+1,newjz);
else
{
update(k,which,value);
dfs(k+1,newjz);
goback(k,which,value);
}
return;
}
if (ans[a[k]-'A']<0)
{
for (int i=0; i<n; i++)
if (used[i]==0)
{
used[i]=1; ans[a[k]-'A']=i;
int tmp1=judge1(k,jw,newjz,which,value);
if (tmp1==1)
{
if (which==0)
dfs(k+1,newjz);
else
{
update(k,which,value);
dfs(k+1,newjz);
goback(k,which,value);
}
which=0;
}
if (tmp1==-1)
for (int j=0; j<n; j++)
if (used[j]==0)
{
used[j]=1; ans[b[k]-'A']=j;
int tmp1=judge1(k,jw,newjz,which,value);
if (tmp1==1)
{
if (which==0)
dfs(k+1,newjz);
else
{
update(k,which,value);
dfs(k+1,newjz);
goback(k,which,value);
}
which=0;
}
used[j]=0; ans[b[k]-'A']=-1;
}
used[i]=0; ans[a[k]-'A']=-1;
}
}
else
{
for (int i=0; i<n; i++)
if (used[i]==0)
{
used[i]=1; ans[b[k]-'A']=i;
if (judge1(k,jw,newjz,which,value)==1)
{
if (which==0)
dfs(k+1,newjz);
else
{
update(k,which,value);
dfs(k+1,newjz);
goback(k,which,value);
}
which=0;
}
used[i]=0; ans[b[k]-'A']=-1;
}
}
}
int main()
{
memset(ans,-1,sizeof(ans));
read();
dfs(1,0);
return 0;
}