似乎可以按位确定每个字母,然后你就得到了一道码农题
所以我们爆搜每个字母的值,然后判断是否合法
朴素的40pts做法
#include<bits/stdc++.h>
using namespace std;
int n,f=0,num[100],vis[100];
string s[10];
void dfs(int x)
{
if(x==n)
{
int xx=0;
for(int i=n-1;i>=0;i--)
{
if((xx+num[s[1][i]-'A']+num[s[2][i]-'A'])%n!=num[s[3][i]-'A']) return;
xx=(xx+num[s[1][i]-'A']+num[s[2][i]-'A'])/n;
}
if(xx==0) f=1;
return;
}
for(int i=0;i<n;i++)
{
if(!vis[i])
{
num[x]=i,vis[i]=1;
dfs(x+1);
if(f==1) return;
vis[i]=0;
}
}
}
int main()
{
cin>>n;
for(int i=1;i<=3;i++) cin>>s[i];
dfs(0);
for(int i=0;i<n;i++) cout<<num[i]<<" ";
return 0;
}
在此基础上考虑剪枝
#include<bits/stdc++.h>
using namespace std;
int n,f=0,num[100],vis[100],in[100],line[100],lc=0;
string s[10];
void dfs(int x)
{
if(in[s[1][0]-'A']<x&&in[s[2][0]-'A']<x&&num[s[1][0]-'A']+num[s[2][0]-'A']>=n) return;//如果最高位上有进位,return
for(int i=0;i<n;i++)
{
if(in[s[1][i]-'A']>=x||in[s[2][i]-'A']>=x||in[s[3][i]-'A']>=x) continue;
int sum=num[s[1][i]-'A']+num[s[2][i]-'A'];
if((sum+1)%n!=num[s[3][i]-'A']&&sum%n!=num[s[3][i]-'A']) return;
}//扫一遍目前已经确定的是不是合法
if(x==n+1)
{
int xx=0;
for(int i=n-1;i>=0;i--)
{
if((xx+num[s[1][i]-'A']+num[s[2][i]-'A'])%n!=num[s[3][i]-'A']) return;
xx=(xx+num[s[1][i]-'A']+num[s[2][i]-'A'])/n;
}
if(xx==0) f=1;
return;
}
for(int i=0;i<n;i++)
{
if(!vis[i])
{
num[line[x]]=i,vis[i]=1;
dfs(x+1);
if(f==1) return;
vis[i]=0;
}
}
}
int main()
{
cin>>n;
for(int i=1;i<=3;i++) cin>>s[i];
for(int i=n-1;i>=0;i--)
for(int j=1;j<=3;j++)
{
if(!in[s[j][i]-'A']) //更改确定字母的顺序,按照出现顺序搜索,可以尽早确定同一位上的数字并进行剪枝
{
line[++lc]=s[j][i]-'A';
in[s[j][i]-'A']=lc;
}
}
dfs(1);
for(int i=0;i<n;i++) cout<<num[i]<<" ";
return 0;
}
加了好多剪枝~然而还是tle
#include<bits/stdc++.h>
using namespace std;
int n,f=0,num[100],vis[100],in[100],line[100],lc=0;
string s[10];
void dfs(int x)
{
if(in[s[1][0]-'A']<x&&in[s[2][0]-'A']<x&&num[s[1][0]-'A']+num[s[2][0]-'A']>=n) return;
for(int i=0;i<n;i++)
{
if(in[s[1][i]-'A']>=x||in[s[2][i]-'A']>=x||in[s[3][i]-'A']>=x) continue;
int sum=num[s[1][i]-'A']+num[s[2][i]-'A'];
if((sum+1)%n!=num[s[3][i]-'A']&&sum%n!=num[s[3][i]-'A']) return;
}
if(x==n+1)
{
int xx=0;
for(int i=n-1;i>=0;i--)
{
if((xx+num[s[1][i]-'A']+num[s[2][i]-'A'])%n!=num[s[3][i]-'A']) return;
xx=(xx+num[s[1][i]-'A']+num[s[2][i]-'A'])/n;
}
if(xx==0) f=1;
return;
}
for(int i=n-1;i>=0;i--)//将数字的枚举顺序改为倒序
{
if(!vis[i])
{
num[line[x]]=i,vis[i]=1;
dfs(x+1);
if(f==1) return;
vis[i]=0;
}
}
}
int main()
{
cin>>n;
for(int i=1;i<=3;i++) cin>>s[i];
for(int i=n-1;i>=0;i--)
for(int j=1;j<=3;j++)
{
if(!in[s[j][i]-'A'])
{
line[++lc]=s[j][i]-'A';
in[s[j][i]-'A']=lc;
}
}
dfs(1);
for(int i=0;i<n;i++) cout<<num[i]<<" ";
return 0;
}
然后就玄学ac了qwq