有点实力的这题,主要是怎么和0交换是一个问题,还有cnator值是一个新知识,这里就不多讲,cantor值是用来判断全排列下,这一串数排第几。看我代码awa.....
//给点支持吧QwQ #include <bits/stdc++.h> using namespace std; typedef long long ll; const int maxn = 11; struct node { int a[5][5]; //九宫格的状态 int x, y, step; //每种状态下(0,0)的坐标,step是到达该状态的步骤 }; ll fact[maxn] = {1,1,2,6,24,120,720,5040,40320,362880,3628800}; // 存储1-10阶乘 int P[maxn]; // 二维转一维 int ans = 0, vis[1000005]; //vis判断某个状态是否已经走过 int dx[5][2]={{1,0},{-1,0},{0,1},{0,-1}}; ll fin; node start, aim; queue<node> Q; ll cantor(node x, int n = 9)//cantor值,不讲了..... { for(int i=1;i<=3;i++) { for(int j=1;j<=3;j++) { P[(i-1)*3+j]=x.a[i][j]; } } ll ans=1; for(int i=1;i<=n;i++) { for(int j=i+1;j<=n;j++) { if(P[i]>P[j]) { ans+=fact[n-i]; // 统计第i位后面有多少比它小的 } } } return ans; } // void print(node x) // { // for(int i = 1; i <= 3; i++) { // for(int j = 1; j <= 3; j++) { // cout << x.a[i][j]<<" "; // } // cout << endl; // } // cout<<endl; // } void bfs()//BFS { Q.push(start);//把start存进Q中 vis[cantor(start)]=1;//把start的cantor值 while(!Q.empty()) //不空就运行 { node f=Q.front();//把Q.front()存下来 node nxt; Q.pop();//把首位吃了 if(cantor(f)==fin) //如果f的cantor值是结束状态的fin的话 { ans=f.step;//ans赋值 break;//跳出 } for(int i=0;i<=4-1;i++) //位移 { int nx=f.x+dx[i][0]; int ny=f.y+dx[i][1]; if(nx>=1&&nx<=3&&ny>=1&&ny<=3) //如果没有出界 { nxt=f;//nxt赋值 swap(nxt.a[f.x][f.y],nxt.a[nx][ny]);//把a数组中的0和这个位置的数交换 nxt.x=nx;//nxt的xy设置 nxt.y=ny; nxt.step=f.step+1;//又走了一步nxt.step=f.step++; if(!vis[cantor(nxt)]) //如果vis[cantor(nxt)]!=1 { vis[cantor(nxt)]=1;//设为1 Q.push(nxt);//把nxt存入Q } } } } } int main() { for(int i=1;i<=3;i++) { for(int j=1;j<=3;j++) { cin>>start.a[i][j];//输入 if(start.a[i][j]==0) //找到那里是可以换的 { start.x=i;//把start的xy设为0的坐标 start.y=j; } } } start.step=0;//step设为零 for(int i=1;i<=3;i++) //输入结束状态 { for(int j=1;j<=3;j++) { cin>>aim.a[i][j]; } } fin=cantor(aim); // 结束状态的cantor值 bfs();//运行 cout<<ans;//输出最少次数 return 0; }
给点支持吧QwQ,马上出BFS.....awa