code1225 八数码Bfs
Posted FuTaimeng
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了code1225 八数码Bfs相关的知识,希望对你有一定的参考价值。
Bfs搜索
1.把棋盘直接作为状态:
#include<iostream> #include<cstring> #include<queue> #include<cstdlib> using namespace std; const int n=9; const int Size=4; int flag; struct Point{ int x,y; }; struct Node{ int board[Size][Size]; Point space; int step; }; int end[]={0, 1,2,3,8,9,4,7,6,5}; int dx[4]={-1,0,1,0}; int dy[4]={0,1,0,-1}; bool visited[400005]; //KT int fac[]={1,1,2,6,24,120,720,5040,40320,362880}; int KT(int s[]){ int ans=0,smallNum; for(int i=1;i<=n;i++){ smallNum=0; for(int j=i+1;j<=n;j++){ if(s[i]>s[j])smallNum++; } ans+=smallNum*fac[n-i]; } return ans; } void InvKT(int k,int s[]){ int t,j; bool v[11]; memset(v,false,sizeof(v)); for(int i=1;i<=n;i++){ t=k/fac[n-i]; for(j=1;j<=n;j++){ if(v[j]==false){ if(t==0)break; else t--; } } s[i]=j; v[j]=true; k%=fac[n-i]; } } //零件 bool isWin(Node k){ for(int i=1;i<=3;i++){ for(int j=1;j<=3;j++){ if(k.board[i][j]!=end[(i-1)*3+j])return false; } } return true; } bool vis(Node k){ int s[11]; for(int i=1;i<=3;i++){ for(int j=1;j<=3;j++){ s[(i-1)*3+j]=k.board[i][j]; } } int num=KT(s); if(visited[num]==true)return true; else{ visited[num]=true; return false; } } bool check(Point p){ if(p.x>=1&&p.y>=1&&p.x<=3&&p.y<=3)return true; else return false; } void swapBoard(Node& k,Point a,Point b){ int temp=k.board[a.x][a.y]; k.board[a.x][a.y]=k.board[b.x][b.y]; k.board[b.x][b.y]=temp; } void outPut(Node a){ cout<<"This is a Node:"<<endl; for(int i=1;i<=3;i++){ for(int j=1;j<=3;j++){ cout<<a.board[i][j]<<‘ ‘; } cout<<endl; } cout<<"Space: "<<a.space.x<<‘ ‘<<a.space.y<<endl; cout<<"Step: "<<a.step<<endl; flag++; if(flag>10)exit(0); } //Bfs int bfs(Node start){ memset(visited,false,sizeof(visited)); queue<Node> q; q.push(start); vis(start); while(!q.empty()){ Node k=q.front(); q.pop(); //outPut(k); for(int i=0;i<4;i++){ Point newSpace=k.space; newSpace.x+=dx[i]; newSpace.y+=dy[i]; if(check(newSpace)){ Node t=k; swapBoard(t,t.space,newSpace); t.space=newSpace; t.step++; if(isWin(t))return t.step; if(!vis(t))q.push(t); } } } return -1; } //Main int main(){ freopen("1225.in","r",stdin); char cc; Node start; for(int i=1;i<=3;i++){ for(int j=1;j<=3;j++){ cin>>cc; if(cc==‘0‘){ start.board[i][j]=9; start.space.x=i; start.space.y=j; } else start.board[i][j]=cc-‘0‘; } } start.step=0; cout<<bfs(start)<<endl; fclose(stdin); return 0; }
测试点#1.in 结果: 内存使用量: 488kB 时间使用量: 1ms
测试点#2.in 结果: 内存使用量: 1128kB 时间使用量: 3ms
测试点#3.in 结果: 内存使用量: 1128kB 时间使用量: 6ms
测试点#4.in 结果: 内存使用量: 620kB 时间使用量: 2ms
测试点#5.in 结果: 内存使用量: 748kB 时间使用量: 1ms
2.把棋盘的康拓作为状态(为A*做准备):
#include<iostream> #include<cstring> #include<queue> #include<cstdlib> using namespace std; const int n=9; const int Size=4; int flag; struct Point{ int x,y; }; int end[]={0, 1,2,3,8,9,4,7,6,5}; int KTend=-1; int dx[4]={-1,0,1,0}; int dy[4]={0,1,0,-1}; bool visited[400005]; int f[400005],step[400005],h[400005]; //KT int fac[]={1,1,2,6,24,120,720,5040,40320,362880}; int KT(int s[]){ int ans=0,smallNum; for(int i=1;i<=n;i++){ smallNum=0; for(int j=i+1;j<=n;j++){ if(s[i]>s[j])smallNum++; } ans+=smallNum*fac[n-i]; } return ans; } int KT(int s[Size][Size]){ int a[11]; for(int i=1;i<=3;i++){ for(int j=1;j<=3;j++){ a[(i-1)*3+j]=s[i][j]; } } return KT(a); } void InvKT(int k,int s[]){ int t,j; bool v[11]; memset(v,false,sizeof(v)); for(int i=1;i<=n;i++){ t=k/fac[n-i]; for(j=1;j<=n;j++){ if(v[j]==false){ if(t==0)break; else t--; } } s[i]=j; v[j]=true; k%=fac[n-i]; } } void InvKT(int k,int s[Size][Size]){ int a[11]; InvKT(k,a); for(int i=1;i<=3;i++){ for(int j=1;j<=3;j++){ s[i][j]=a[(i-1)*3+j]; } } } //零件 bool isWin(int kt){ if(KTend==-1)KTend=KT(end); return KTend==kt; } bool vis(int kt){ if(visited[kt]==true)return true; else{ visited[kt]=true; return false; } } bool check(Point p){ if(p.x>=1&&p.y>=1&&p.x<=3&&p.y<=3)return true; else return false; } void swapBoard(int board[Size][Size],Point a,Point b){ int temp=board[a.x][a.y]; board[a.x][a.y]=board[b.x][b.y]; board[b.x][b.y]=temp; } Point getSpacePoint(int board[Size][Size]){ Point p; for(int i=1;i<=3;i++){ for(int j=1;j<=3;j++){ if(board[i][j]==9){ p.x=i; p.y=j; break; } } } return p; } void copy(int a[Size][Size],int b[Size][Size]){ for(int i=1;i<=3;i++){ for(int j=1;j<=3;j++){ b[i][j]=a[i][j]; } } } //Bfs int bfs(int start){ memset(visited,false,sizeof(visited)); queue<int> q; q.push(start); vis(start); step[start]=0; while(!q.empty()){ int kt=q.front(); q.pop(); int s[Size][Size]; InvKT(kt,s); Point space=getSpacePoint(s); for(int i=0;i<4;i++){ Point space2=space; space2.x+=dx[i]; space2.y+=dy[i]; if(check(space2)){ int s2[Size][Size]; copy(s,s2); swapBoard(s2,space,space2); int kt2=KT(s2); step[kt2]=step[kt]+1; if(isWin(kt2))return step[kt2]; if(!vis(kt2))q.push(kt2); } } } return -1; } //Main int main(){ freopen("1225.in","r",stdin); char cc; int start[11]; for(int i=1;i<=n;i++){ cin>>cc; if(cc==‘0‘)start[i]=9; else start[i]=cc-‘0‘; } int KTstart=KT(start); cout<<bfs(KTstart)<<endl; fclose(stdin); return 0; }
测试点#1.in 结果: 内存使用量: 620kB 时间使用量: 1ms
测试点#2.in 结果: 内存使用量: 2024kB 时间使用量: 8ms
测试点#3.in 结果: 内存使用量: 2028kB 时间使用量: 6ms
测试点#4.in 结果: 内存使用量: 1772kB 时间使用量: 2ms
测试点#5.in 结果: 内存使用量: 1772kB 时间使用量: 3ms
以上是关于code1225 八数码Bfs的主要内容,如果未能解决你的问题,请参考以下文章