两个题目都是类似的。八数码遍历的基本问题。
自己早先前看过八数码问题,写了一遍,不过。
后面对着解题报告,又按自己的思路写了一遍,还是不过。老是runtime error。
不知道错在哪里,调试废了我一天。哪位有心研究下能指点出来感激不尽啊。打算放弃了。因为已经了解其中的算法了。就是....神啊,求指导。呜呜。
就是模拟跳马和移动格子,然后进行广搜,用hash判重。关键是hash判重。
UVA10422:
#include<iostream> #include<cstring> using namespace std; #define MaxHash 1<<25 #define Max 600000 int Hash[MaxHash]; int state[Max][25]; int goal[25]={1,1,1,1,1,0,1,1,1,1,0,0,2,1,1,0,0,0,0,1,0,0,0,0,0}; int dx[]={1,1,-1,-1,2,2,-2,-2}; int dy[]={2,-2,2,-2,1,-1,1,-1}; int dist[Max]; bool try_to_insert(int n){ int i,ans,k; for(i=0,ans=0,k=0;i<25;i++){ if(state[n][i]){ ans+=(1<<k)*state[n][i]; k++; } } ans+=1; if(Hash[ans]) return false; else return true; } int bfs(){ int front=1,rear=2,newx,newxy,x,y,prexy,i,newy; while(front<rear){ if(dist[front]>10) return front; for(prexy=0;prexy<25;prexy++) if(state[front][prexy]==2) break; x=prexy/5; y=prexy%5; for(i=0;i<8;i++){ newx=x+dx[i]; newy=y+dy[i]; newxy=newx*5+newy; if(newx>=0&&newy>=0&&newx<5&&newy<5){ memcpy(state[rear],state[front],sizeof(state[front])); state[rear][prexy]=state[front][newxy]; state[rear][newxy]=state[front][prexy]; dist[rear]=dist[front]+1; if(try_to_insert(rear)){ if(memcmp(state[rear],goal,sizeof(goal))==0) return rear; rear++; } } } front++; } return 0; } int main(){ int test_case,steps; char str[6]; cin >> test_case; cin.get(); while(test_case--){ memset(Hash,0,sizeof(Hash)); memset(dist,0,sizeof(dist)); for(int i=0,k=0;i<5;i++){ cin.getline(str,6); for(int j=0;j<5;j++){ if(str[j]=='1') state[1][k++]=1; else if(str[j]=='0') state[1][k++]=0; else state[1][k++]=2; } } if(memcmp(state[1],goal,sizeof(goal))!=0) steps=bfs(); else{ cout << "Solvable in 0 move(s).\n"; } if(dist[steps]<11) cout << "Solvable in " << dist[steps] << " move(s).\n"; else cout << "Unsolvable in less than 11 move(s)."; } return 0; }
#include<iostream> #include<string> #include<cstring> using namespace std; const int Maxstate=100000; const int MaxHashTable=1000003; struct Node{ int state[9]; string str; }; Node st[Maxstate]; int head[MaxHashTable],Next[Maxstate]; int dx[]={1,-1,0,0}; int dy[]={0,0,-1,1}; char path[]="DULR"; int Hash(Node s){ int i,v; for(i=0,v=0;i<9;i++) v=v*10+s.state[i]; return v%MaxHashTable; } bool try_to_insert(int n){ int h=Hash(st[n]); int u=head[h]; while(u){ if(memcmp(st[u].state,st[n].state,sizeof(st[u].state))==0) return false; u=Next[u]; } Next[n]=head[h]; head[h]=n; return true; } int bfs(void){ int rear,front,i,x,y,prexy,newxy,newx,newy; front=1; rear=2; while(front<rear){ Node &s=st[front]; for(prexy=0;prexy<9;prexy++){ if(!s.state[prexy]) break; } x=prexy/3; y=prexy%3; for(i=0;i<4;i++){ newx=x+dx[i]; newy=y+dy[i]; st[rear].str=st[front].str+path[i]; newxy=newx*3+newy; if(newx>=0&&newy>=0&&newx<3&&newy<3){ Node &t=st[rear]; memcpy(t.state,s.state,sizeof(s.state)); t.state[prexy]=s.state[newxy]; t.state[newxy]=s.state[prexy]; if(try_to_insert(rear)) rear++; } } front++; } return rear; } int main() { int test_case,i,j,num_case=0,rear; cin >> test_case; cin.get(); while(test_case--){ num_case++; cout << "Puzzle #" << num_case << endl; memset(st,0,sizeof(st)); memset(head,0,sizeof(head)); memset(Next,0,sizeof(Next)); for(i=0;i<9;i++) cin>>st[1].state[i]; try_to_insert(1); rear=bfs(); for(i=0;i<3;i++){ for(j=0;j<3;j++){ cout << st[rear].state[i*3+j]; } cout << endl; } cout << st[rear].str << endl; } return 0; }