这道题其实就是纸老虎,看上去10e8很大,其实根本就不会达到那么大。若有解,必定不会超过4个字符。
reason:AA是不是就等于BB了?而AAA是不是又等于B了?所以A和B一共出现2次。而DD抵消,CC抵消,所以各只出现一次,所以最多四次。
了解到这一切之后就知道忧愁祸患使人生存,安逸享乐会使人死亡的道理了????,那么直接上暴力深搜伺候
细节在代码里嘤
没人 比我 更懂 code:
#include <bits/stdc++.h>
using namespace std;
int k;
int a[4][4] , b[4][4]; //当前 / 目标
map<char , int> f; //记录出现次数
map<char , int> bz; //变阻真帅(误) 没实际作用,忘删了而已
stack<char> ans; //目前搜到的答案
stack<char> eans; //最优解
bool pd(){ //判断是否到达
for(int i = 1; i <= 3; i++)
for(int j = 1; j <= 3; j++) if(a[i][j] != b[i][j]) return 0;
return 1;
}
void search(){
//cout << ans.top();
/*cout << endl;
for(int i = 1; i <= 3; i++){
for(int j = 1; j <= 3; j++) cout << a[i][j] << " ";
cout << endl;
}*/
if(pd()){
if(ans.size() < eans.size()){
while(!eans.empty()) eans.pop();
char ccc[60];
int i = 1;
while(!ans.empty()){ //!!!!特别注意栈是先进后出,所以得用这种转移方式
ccc[i] = ans.top();
ans.pop();
i++;
}
for(int j = i; j >= 1; j--){
eans.push(ccc[j]);
ans.push(ccc[j]);
}
}
k = 1; //有解
}
if(f['A'] + f['B'] != 2){ //AB总共不出现两次/剪枝
bz['A']++;
f['A']++;
ans.push('A');
int ca[4][4];
for(int i = 1; i <= 3; i++)
for(int j = 1; j <= 3; j++) ca[i][j] = a[i][j];
for(int i = 1; i <= 3; i++)
for(int j = 1; j <= 3; j++) a[i][j] = ca[3 - j + 1][i];
search();
for(int i = 1; i <= 3; i++)
for(int j = 1; j <= 3; j++) a[i][j] = ca[i][j];
ans.pop();
f['A']--;
}
if(f['A'] + f['B'] != 2){
bz['B']++;
f['B']++;
ans.push('B');
int cb[4][4];
for(int i = 1; i <= 3; i++)
for(int j = 1; j <= 3; j++) cb[i][j] = a[i][j];
for(int i = 1; i<= 3; i++)
for(int j = 1; j <= 3; j++) a[i][j] = cb[j][3 - i + 1];
search();
for(int i = 1; i <= 3; i++)
for(int j = 1; j <= 3; j++) a[i][j] = cb[i][j];
ans.pop();
f['B']--;
}
if(!f['C']){
bz['C']++;
f['C']++;
ans.push('C');
int cc[4][4];
for(int i = 1; i <= 3; i++)
for(int j = 1; j <= 3; j++) cc[i][j] = a[i][j];
swap(a[1][1] , a[1][3]) , swap(a[2][1] , a[2][3]) , swap(a[3][1] , a[3][3]);
search();
for(int i = 1; i <= 3; i++)
for(int j = 1; j <= 3; j++) a[i][j] = cc[i][j];
ans.pop();
f['C']--;
}
if(!f['D']){
bz['D']++;
f['D']++;
ans.push('D');
int cd[4][4];
for(int i = 1; i <= 3; i++)
for(int j = 1; j <= 3; j++) cd[i][j] = a[i][j];
swap(a[1][1] , a[3][1]) , swap(a[1][2] , a[3][2]) , swap(a[1][3] , a[3][3]);
search();
for(int i = 1; i <= 3; i++)
for(int j = 1; j <= 3; j++) a[i][j] = cd[i][j];
ans.pop();
f['D']--;
}
}
int main(){
for(int i = 1; i <= 10; i++) eans.push('Z');
for(int i = 1; i <= 3; i++)
for(int j = 1; j <= 3; j++) cin >> a[i][j];
for(int i = 1; i <= 3; i++)
for(int j = 1; j <= 3; j++) cin >> b[i][j];
if(pd()){ //!!!!!系列至少不为0,所以要AB一下
cout << "AB";
return 0;
}
if(a[2][2] != b[2][2]){ //中间一直不变,中间不等相当于不可能一样
cout << "Poland cannot into space!!!";
return 0;
}
search();
if(!k) cout << "Poland cannot into space!!!";
else{
char ccc[60];
int i = 1;
while(!eans.empty()){
ccc[i] = eans.top();
eans.pop();
i++;
}
for(int j = i; j >= 1; j--){
if(ccc[j] == 'A' || ccc[j] == 'B' || ccc[j] == 'C' || ccc[j] == 'D') cout << ccc[j];
}
}
return 0;
}
/*
3 4 5
6 7 8
1 2 3
1 2 3
6 7 8
3 4 5
*/
吐槽:这种大模拟/搜索是真的ex,做一次死一次orz