思路
这道题我们首先把输入的字母按出现顺序放到一个数组里。
这样如果直接暴力的话会超时,所以考虑要优化。
如果当前有值没有被枚举过,我们就可以设一个标记为 − 1 -1 −1。
我们肯定从低位到高位算,
如果在设为 − 1 -1 −1 之后又有一位上三个值都被枚举过了的话,
那么我们就分成是否被进位讨论,
没有进位,那么 a + b a+b a+b 的个位就要等于 c c c,
有进位,那么 a + b + 1 a+b+1 a+b+1 的个位就要等于c,
如果前面所有位的值都被枚举过了,
那我们就可以直接进行加法进位,
如果两个条件都不满足,则失败,直接返回即可。
代码
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
int en[75],bj[27],num[27];
string s[3];
char a[27];
int n,c,w;
bool check()
{
int jw=0,t=0;
for(int i=s[0].size()-1; i>=0; i--)
{
int a=num[s[0][i]-64];
int b=num[s[1][i]-64];
int c=num[s[2][i]-64];
if(a==-1||b==-1||c==-1)
{
t=-1;
continue;
}
if(t==-1)
{
if((a+b)%n!=c&&(a+b+1)%n!=c)
return 0;
if(((a+b)/n>0||(a+b+1)/n>0)&&i==0)
return 0;
}
else
{
if((a+b+jw)%n!=c)
return 0;
jw=(a+b+jw)/n;
if(jw>0&&i==0)
return 0;
}
}
return 1;
}
void dfs(int wx)
{
//cout<<wx<<endl;
if(w==1)
return;
if(wx>n)
{
for(int i=1; i<=n; i++)
cout<<num[i]<<" ";
w=1;
return;
}
for(int i=0; i<n; i++)
{
if(bj[i]==0)
{
num[a[wx]-64]=i;
bj[i]=1;
if(check())
dfs(wx+1);
num[a[wx]-64]=-1;
bj[i]=0;
}
}
}
int main()
{
memset(num,-1,sizeof(num));
cin>>n;
cin>>s[0]>>s[1]>>s[2];
for(int i=s[0].size()-1; i>=0; i--)
for(int j=0; j<=2; j++)
{
if(en[s[j][i]-64]==0)
{
a[++c]=s[j][i];
en[s[j][i]-64]=1;
}
}
dfs(1);
return 0;
}