魔板 Magic Squares
【题目描述】:
魔板 Magic Squares
【思路】:
是不是感觉和八数码有点像?
显而易见的宽搜,把魔板的状态表示为排列,则状态最多有\(8! = 40320\)种,空间是可以接受的,对于是第几个排列可以用康拓展开来实现(我想在做八数码的时候你们都深知这个套路),然后根据题目中的三种方式转移状态,每个状态转移出\(3\)个子状态,注意判重!,一旦目标状态出现,那个所搜索的层数一定是能得到该状态的最小步数。最后就是代码细节多,要仔细。
#include<cstdio>
#include<queue>
#include<algorithm>
using namespace std;
int calc[]={1,1,2,6,24,120,720,5040};
int mp[3][5];
bool vis[45000];int rest[10];int a[45000][10];int ans;int Ans;int step[45000];int st;
char last[45000];char endd[45000];int fa[45000];
inline bool judge(){//康拓展开标记
ans = 0;int id = 7;
for(int i=1;i<=8;++i) rest[i] = i-1;
for(int i=1;i<=4;++i){
ans += (rest[mp[1][i]]) * calc[id];
for(int j=mp[1][i]+1;j<=8;++j) rest[j]--;
id--;
}
for(int i=1;i<4;++i){
ans += (rest[mp[2][i]]) * calc[id];
for(int j=mp[2][i]+1;j<=8;++j) rest[j]--;
id--;
}
ans++;
if(vis[ans]){
if(ans == Ans) return 1;
else return 0;
}
vis[ans] = 1;
id = 0;
for(int i=1;i<=4;++i) a[ans][++id] = mp[1][i];
for(int i=1;i<=4;++i) a[ans][++id] = mp[2][i];
return 1;
}
inline bool A(int x){
int id = 0;
for(int i=1;i<=4;++i) mp[1][i] = a[x][++id];
for(int i=1;i<=4;++i) mp[2][i] = a[x][++id];
swap(mp[1] , mp[2]);
return judge();
}
inline bool B(int x){
int id = 0;
for(int i=1;i<=4;++i) mp[1][i] = a[x][++id];
for(int i=1;i<=4;++i) mp[2][i] = a[x][++id];
swap(mp[1][4] , mp[1][1]);
swap(mp[2][4] , mp[2][1]);
for(int i=4;i>=3;--i){
swap(mp[1][i] , mp[1][i-1]);
swap(mp[2][i] , mp[2][i-1]);
}
return judge();
}
inline bool C(int x){
int id = 0;
for(int i=1;i<=4;++i) mp[1][i] = a[x][++id];
for(int i=1;i<=4;++i) mp[2][i] = a[x][++id];
swap(mp[1][2] , mp[1][3]);
swap(mp[1][2] , mp[2][2]);
swap(mp[2][2] , mp[2][3]);
return judge();
}
queue<int>q;
inline void bfs(){
q.push(st);
while(!q.empty()){
int u = q.front();q.pop();
if(A(u)){
q.push(ans),step[ans] = step[u] + 1;
last[ans] = 'A';fa[ans] = u;
if(ans == Ans){printf("%d\n",step[ans]);return ;}
}
if(B(u)){
q.push(ans),step[ans] = step[u] + 1;
last[ans] = 'B';fa[ans] = u;
if(ans == Ans){printf("%d\n",step[ans]);return ;}
}
if(C(u)){
q.push(ans),step[ans] = step[u] + 1;
last[ans] = 'C';fa[ans] = u;
if(ans == Ans){printf("%d\n",step[ans]);return ;}
}
}
}
int main(){
for(int i=1;i<=4;++i) mp[1][i] = i;
for(int i=1;i<=4;++i) mp[2][i] = 9 - i;
judge();st = ans;last[st] = '&';
for(int i=1;i<=4;++i) a[Ans][i] = i;
for(int i=5;i<=8;++i) a[Ans][i] = 13-i;
for(int i=1;i<=4;++i) scanf("%d",&mp[1][i]);
for(int i=1;i<=4;++i) scanf("%d",&mp[2][5-i]);
judge();Ans = ans;
if(st == Ans){
puts("0");
return 0;
}
bfs();
int x = Ans;int num = 0;
while(last[x] != '&'){
endd[++num] = last[x];
x = fa[x];
}
for(int i=num;i>=1;--i) printf("%c",endd[i]);
return 0;
}