藍橋杯——九宮重排(八數碼問題)
阿新 • • 發佈:2019-02-01
#include<iostream> #include<cstdio> #include<cstring> #include<vector> #include<algorithm> #include<cmath> #include<queue> #include<map> #include<stack> #include<set> using namespace std; typedef long long ll; const int maxn=20010; const int inf=0xfffffff; char maze[5][5]; char ans[5][5]; char a[10],b[10],ai=1,bi=1; bool isjie(){ int i,j; int ans1=0; for(i=2;i<=9;++i){ if(a[i]=='.') continue; int sum=0; for(j=1;j<i;++j){ if(a[j]=='.') continue; if(a[j]>a[i]){ sum++; } } ans1+=sum; } int ans2=0; for(i=2;i<=9;++i){ if(b[i]=='.') continue; int sum=0; for(j=1;j<i;++j){ if(b[j]=='.') continue; if(b[j]>b[i]){ sum++; } } ans2+=sum; } ans1=ans1&1; ans2=ans2&1; if(ans1^ans2){ return false; } return true; } int geth(){ int i,j,sum=0; for(i=1;i<=3;++i){ for(j=1;j<=3;++j){ char c=ans[i][j]; if(c=='.') continue; for(int k=1;k<=3;++k){ for(int l=1;l<=3;++l){ if(maze[k][l]==c){ sum+=fabs(i-k)+fabs(j-l); break; } } } } } return sum; } bool flag; int dr[4][2]={-1,0,0,-1,0,1,1,0}; int q; void dfs(int x,int y,int last,int now,int step){ int h=geth(); if(now<=step){ if(h==0){ flag=true; q=now; return; }else if(now==step) return; } int nx,ny; for(int i=0;i<4;++i){ if(i+last==3&&now>0) continue; nx=x+dr[i][0]; ny=y+dr[i][1]; if(nx>=1&&nx<=3&&ny>=1&&ny<=3){ swap(maze[x][y],maze[nx][ny]); if(geth()+now<=step && !flag){ dfs(nx,ny,i,now+1,step); if(flag) return; } swap(maze[x][y],maze[nx][ny]); } } } int main(){ int i,j; int st,se; for(i=1;i<=3;++i) for(j=1;j<=3;++j){ scanf("%c",&maze[i][j]); a[ai++]=maze[i][j]; if(maze[i][j]=='.'){ st=i,se=j; } } getchar(); for(i=1;i<=3;++i) for(j=1;j<=3;++j){ scanf("%c",&ans[i][j]); b[bi++]=ans[i][j]; } if(!isjie()){ puts("-1"); return 0; } int dep=1; while(1){ flag=false; dfs(st,se,0,0,dep); if(flag){ printf("%d\n",q); break; } ++dep; } return 0; }