【问题描述】
【输入文件】
【输出文件】
解题思路:搜索的方法还是很明显的。。主要问题在搜索顺序和剪枝上了。由于是加法有进位,所以从低位向高位搜。剪枝有以下几点:1.若一列的两个数已知,但是第三个数与这两个数推出的结果矛盾;2.每搜出一个字母都向更高位搜索,如果出现像1一样的矛盾就剪枝。。还有一些想不起了。。另外对于每一个字母从大往小搜会比从小往下搜快,,,【noip数据的特点?】
代码(死活有一个点过不去):
#include
#include
#include
#include
#include
using namespace std;
intn,a[30],b[30],c[30],u[30]={0},un[30]={0},f[30],q[30],i,sum,j;
string s1,s2,s3;
int pan()
{int d=0,i;
for (i=n;i>=1;i--)
{if (u[a[i]]==0||u[b[i]]==0) return 0;
if(u[a[i]]==0&&u[b[i]]==1&&u[c[i]]==1&&un[f[c[i]]-f[b[i]]]==1&&un[f[c[i]]+n-f[b[i]]]==1)return -1;
if(u[a[i]]==0&&u[b[i]]==1&&u[c[i]]==1&&un[f[c[i]]-f[b[i]]]==0)f[a[i]]=f[c[i]]-f[b[i]];
if(u[a[i]]==0&&u[b[i]]==1&&u[c[i]]==1&&un[f[c[i]]-f[b[i]]+n]==0)f[a[i]]=f[c[i]]-f[b[i]]+n;
if(u[a[i]]==1&&u[b[i]]==0&&u[c[i]]==1&&un[f[c[i]]-f[a[i]]]==1&&un[f[c[i]]+n-f[a[i]]]==1)return -1;
if(u[a[i]]==1&&u[b[i]]==0&&u[c[i]]==1&&un[f[c[i]]-f[a[i]]]==0)f[a[i]]=f[c[i]]-f[a[i]];
if(u[a[i]]==1&&u[b[i]]==0&&u[c[i]]==1&&un[f[c[i]]-f[a[i]]+n]==0)f[a[i]]=f[c[i]]-f[a[i]]+n;
d+=f[a[i]]+f[b[i]];
if(u[a[i]]==1&&u[b[i]]==1&&u[c[i]]==0&&un[d%n]==1)return -1;
if(u[a[i]]==1&&u[b[i]]==1&&u[c[i]]==0&&un[d%n]==0){d=d/n;continue;}
if (d%n!=f[c[i]]) return -1;
d=d/n;
}
return 1;
}
void dfs(int k)
{int i,p;
p=pan();
if (p==-1) return;
if (p==1)
{for (i=1;i<=n-1;i++) printf("%d ",f[i]);
printf("%d\n",f[n]);exit(0);
}
for (i=n-1;i>=0;i--)
if (un[i]==0) {
f[q[k]]=i;
u[q[k]]=1;
un[i]=1;
dfs(k+1);
u[q[k]]=0;
f[q[k]]=0;
un[i]=0;
}
}
int main()
{scanf("%d",&n);
cin>>s1;
cin>>s2;
cin>>s3;
sum=0;
for (i=1;i<=n;i++)
{a[i]=(int)s1[i-1]-64;
b[i]=(int)s2[i-1]-64;
c[i]=(int)s3[i-1]-64;
}
for (i=n;i>=1;i--)
{if (u[a[i]]==0) {sum++;u[a[i]]=1;q[sum]=a[i];}
if (u[b[i]]==0) {sum++;u[b[i]]=1;q[sum]=b[i];}
if (u[c[i]]==0) {sum++;u[c[i]]=1;q[sum]=c[i];}
}
memset(u,0,sizeof(u));//printf("*");
dfs(1);
}