题目连接
https://www.luogu.com.cn/problem/P1013
首先,看到案例能发现,只有可能出现n-1种字母(数字)考虑一下是几进制,不可能是小于n-1进制,反证,如果小于n-1进制那么最大的那个数就不该用一个字母表示了。
例如4进制,就该是0,1,2,3,10;如果是三进制的话,那个三就该用10表示了
再想一下大于n-1进制呢,例如本体案例:
+ L K V E L L K V E K K V E KL V V E KL KK E E KL KK KV
这是4进制,如果用5进制写出来是怎样?结果如下:
+ L K V E L L K V E K K V E 5 V V E 5 KL E E 5 KL KK
这将会多出一个元素,4个元素无法表示5;
所以本题肯定是n-1进制;
接下俩就好办了,那n-1个元素坑定是0~n-2;经过排列组合(bfs),比如3个元素的排列组合
0,1,2
0,2,1
1,0,2
1,2,0
2,0,1
2,1,0
把这些数带进去与案例比较,如果有符合就输出答案呗。
以下是我的代码,未优化
#include<bits/stdc++.h>
using namespace std;
#define int long long
char a[15][15][3];
int mp[200];
int n;
int pd()//判断是否符合案例
{
int flag = 0;
for(int i = 1;i<n;i++){
for(int j = 1;j<n;j++){
int temp = 0,le = strlen(a[i][j]);
for(int l = 0;l<le;l++){
temp+=pow(n-1,l)*mp[a[i][j][le-l-1]];
}
if(mp[a[i][0][0]]+mp[a[0][j][0]]!=temp){
flag = 1;
break;
}
}
if(flag == 1)break;
}
return flag;
}
int shu[] = {0,0,1,2,3,4,5,6,7,8,9},vis[11];
int shu1[11];
int flag = 0;
void bfs(int x)
{
if(x==n){
for(int i= 1;i<n;i++){
mp[a[0][i][0]] = shu1[i];
}
flag = !pd();
return;
}
for(int i = 1;i<n;i++){
if(vis[i]==0&&flag==0){//flag等于0有符合案例的
shu1[x] =shu[i];
vis[i] = 1;
bfs(x+1);
vis[i] = 0;
}
}
}
signed main()
{
// ios::sync_with_stdio(false);
cin >> n;
for(int i = 0;i<n;i++){
for(int j = 0;j<n;j++){
scanf("%s",a[i][j]);
}
}
bfs(1);
if(flag == 1){
for(int i = 1;i<n;i++){
printf("%c=%lld ",a[0][i][0],shu1[i]);
}
printf("\n");
printf("%lld\n",n-1);
}
else printf("ERROR!");
}