思路
我直接暴力枚举可能的值,每一位计算,然而洛谷的数据是错的。。。
其实好有更好的做法,在一个加法表里,字母出现的次数是多少,减一就是对应的值,只算出现一次的。
代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
char a1[15][15][15], b1[15], cnt;
int ans[15], n, is[15], map [300];
bool vis[15];
bool check(){
int num1[15], pp1 = 0, num2[15], pp2 = 0, pp3 = 0;
for(int i = 2; i <= n; i ++){
for(int j = 2; j <= n; j ++){
memset(num1, 0, sizeof num1);
memset(num2, 0, sizeof num2);
pp1 = pp2 = pp3 = 0;
for(int k = 6; k >= 1; k --){
if(a1[i][j][k] != '\0'){
pp3 = k;
break;
}
}
if(pp3 > 1) continue;
for(int k = pp3; a1[i][j][k] >= 1; k --)
num1[++pp1] = map[a1[i][j][k]];
num2[++pp2] += (map[a1[1][i][1]] + map[a1[1][j][1]]);
while(num2[pp2] / (n-1)){
num2[pp2+1] += num2[pp2] / (n-1);
num2[pp2++] %= (n-1);
}
if(pp1 != pp2) return false;
for(int i = 1; i <= pp1; i ++)
if(num2[i] != num1[i]) return false;
}
}
return true;
}
bool dfs(int now){
if(now > n-1){
if(check()){
for(int i = 1; i < n; i ++)
printf("%c=%d ", b1[i], ans[i]);
printf("\n");
return true;
}else return false;
}
for(int i = 0; i < n-1; i ++){
if(!vis[i]){
vis[i] = 1;
ans[now] = i;
map[b1[now]] = i;
if(dfs(now+1)) return true;
vis[i] = 0;
}
}
return false;
}
int main(){
scanf("%d", &n);
for(int i = 1; i <= n; i ++)
for(int j = 1; j <= n; j ++)
scanf("%s", a1[i][j]+1);
for(int i = 2; i <= n; i ++)
b1[++cnt] = a1[1][i][1];
if(dfs(1)) printf("%d", n-1);
else printf("ERROR!");
return 0;
}