标签:简单 style queue class bool 棋盘 include pid code
敲黑板当当当~
从今晚(28)起,日更 “咸鱼烤前的垂死挣扎”。
日更的内容是对当天学习的模板做一个小小的总结
日更的的口号是——
不是还没到最后一刻嘛~
小哥哥再坚持一下嘛~
2019-10-28
搜索
P1379 八数码难题
题面:
在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字。棋盘中留有一个空格,空格用0来表示。空格周围的棋子可以移到空格中。要求解的问题是:给出一种初始布局(初始状态)和目标布局(为了使题目简单,设目标状态为123804765),找到一种最少步骤的移动方法,实现从初始布局到目标布局的转变。
思路:
隐形图要做转化处理(压缩,解压),然后就是跑上一圈BFS啦~
注意特判(^U^)ノ~YO
(听说还可以用康托展开处理,待我学会去去就来~)
1 #include<cstdio> 2 #include<queue> 3 #include<iostream> 4 #include<algorithm> 5 using namespace std; 6 7 struct node{ 8 string s; 9 int step; 10 }a,e; 11 int sum,ans,tot; 12 int dx[4]={-1,0,0,1},dy[4]={0,1,-1,0}; 13 char b[3][3]; 14 string n,m; 15 bool flag[88888888]; 16 queue <node > q; 17 18 string change(){ 19 string c; 20 sum=0; 21 for(int i=0;i<3;i++) 22 for(int j=0;j<3;j++){ 23 c+=b[i][j]; 24 if(!(i==2&&j==2))sum=sum*10+b[i][j]-‘0‘; //注意求的是前 8位的和 25 } 26 return c; 27 } 28 29 void bfs(){ 30 while(!q.empty()){ 31 int tot=0,x,y; 32 a=q.front(); 33 q.pop(); 34 for(int i=0;i<3;i++) // 解压 35 for(int j=0;j<3;j++){ 36 if(a.s[tot]==‘0‘) x=i,y=j; 37 b[i][j]=a.s[tot++]; 38 } 39 for(int i=0;i<4;i++){ // 四个方向扫一遍 40 if(x+dx[i]>-1&&x+dx[i]<3&&y+dy[i]>-1&&y+dy[i]<3){ 41 swap(b[x][y],b[x+dx[i]][y+dy[i]]); 42 e.s=change(); // 压缩->字符串 43 if(e.s=="123804765"){ 44 printf("%d",a.step+1); 45 exit(0); 46 } 47 if(!flag[sum]){ 48 flag[sum]=1; 49 e.step=a.step+1; 50 q.push(e); 51 52 } 53 swap(b[x][y],b[x+dx[i]][y+dy[i]]); //回溯 54 } 55 } 56 } 57 } 58 59 int main() 60 { 61 cin>>n; 62 m="123804765"; 63 a.s=n,a.step=0; 64 q.push(a); 65 for(int i=0;i<8;i++) sum=sum*10+n[i]-‘0‘; 66 for(int i=0;i<8;i++) ans=ans*10+m[i]-‘0‘; 67 flag[sum]=1; 68 69 if(sum==ans) printf("0"); //注意特判 70 else bfs(); 71 72 return 0; 73 }
标签:简单 style queue class bool 棋盘 include pid code
原文地址:https://www.cnblogs.com/RR-Jin/p/11756302.html