全排列
Chivas-Regal
#
# 洛谷P1013_进制位
# 🔗
# 💡
这个表的意思是,
由于除加号之外最多有 个元素,所以其实就是 进制
由于 不是很大,所以可以直接枚举 的全排列,这个全排列相当于是对每一个单字母的映射
我们枚举到一个排列对中心的所有结果检查一下就行了,如果可以就输出这一个排列
检查方式其实大可不必模拟进制,如果两个数在一个进制下不一样,那么在别的进制下也不一样,所以我们转成十进制直接看一下等不等就行了
# ✅
#include <iostream>
#include <map>
#include <vector>
#include <queue>
#include <algorithm>
#define ll long long
using namespace std;
const int N = 15;
int n;
string s[N][N];
vector<char> chr; // 单字符
map<char, int> mp; // 映射
bool flag;
inline bool check ( int i, int j ) { // s[i][0] + s[0][j] = s[i][j] ?
int this_num = 0; for ( int k = 0; k < s[i][j].size(); k ++ ) this_num = this_num * (n - 1) + mp[s[i][j][k]];
int i_num = mp[s[i][0][0]];
int j_num = mp[s[0][j][0]];
return this_num == i_num + j_num;
}
inline void Solve () {
vector<int> vec; for ( int i = 0; i < n - 1; i ++ ) vec.push_back(i);
do {
for ( int i = 0; i < n - 1; i ++ ) mp[chr[i]] = vec[i];
for ( int i = 1; i < n; i ++ ) {
for ( int j = 1; j < n; j ++ ) {
if ( !check(i, j) ) goto end;
}
}
flag = true;
for ( int i = 0; i < chr.size(); i ++ ) {
if ( i ) cout << " ";
cout << chr[i] << "=" << vec[i];
} break;
end:;
} while ( next_permutation ( vec.begin(), vec.end() ) );
}
int main () {
cin >> n;
for ( int i = 0; i < n; i ++ ) for ( int j = 0; j < n; j ++ ) cin >> s[i][j];
for ( int i = 1; i < n; i ++ ) chr.push_back ( s[0][i][0] );
Solve ();
if ( flag ) cout << endl << n - 1 << endl;
else cout << "ERROR!" << endl;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50