题目大意
给一组n进制加法竖式,位数必为n,可以有前导零,每个字母对应一个不同的数字,求一组解。保证有解且唯一。
思路
我们显然只能用dfs解决该题目,所以需要剪枝
剪枝1:我们模拟手动计算,如果在当前情况下已经无解马上回溯
剪枝2:因为解有且唯一,我们一旦找到解就马上输出并结束程序
code:
#include<cstdio>
#include<queue>
#include<iostream>
#include<map>
#include<cstring>
#include<algorithm>
using namespace std;
int n,tot,no[27];
bool ow,vis[27],us[27];
char o[3][27],cr[27];
bool check()
{
int x=0;
for (int i=n-1;i>=0;i--)
{
int add1=no[o[0][i]-'A'],add2=no[o[1][i]-'A'],he=no[o[2][i]-'A'];
if (add1!=-1&&add2!=-1&&he!=-1)
{
if (x==-1)
{
if ((add1+add2)%n!=he&&(add1+add2+1)%n!=he)
{
return 0;
}
if (i==0&&add1+add2>=n)
{
return 0;
}
}
else
{
if ((add1+add2+x)%n!=he)
{
return 0;
}
if ((add1+add2+x)>=n&&i==0)
{
return 0;
}
x=(add1+add2+x)/n;
}
}
else x=-1;
}
return 1;
}
bool dfs(int x)
{
if (x==tot)
{
return 1;
}
for (int i=0;i<n;i++)
{
if (us[i]==0)
{
us[i]=1;
no[cr[x]-'A']=i;
if (check()&&dfs(x+1)) return 1;
us[i]=0;
}
}
no[cr[x]-'A']=-1;
return 0;
}
int main()
{
memset(no,-1,sizeof(no));
scanf("%d",&n);
for (int i=0;i<3;i++)
{
scanf("%s",o[i]);
}
for (int i=n-1;i>=0;i--) for (int j=0;j<3;j++)
{
if (vis[o[j][i]-'A']==0)
{
vis[o[j][i]-'A']=1;
cr[tot++]=o[j][i];
}
}
dfs(0);
for (int i=0;i<n;i++) printf("%d ",no[i]);
return 0;
}
致盯着ybtoj系列的OIer:有些ybtoj的题目缺失,是因为之前已经做过重题的题解,就不再补发了