小记:8数码境界还只有第三重,还要继续加油。
做法:第一重,stl + bfs 暴力, 9!数量级,在重复询问的状态下,超时是必然的
第二重,hash + bfs ,自己做hash函数,自己想个hash函数出来,hdu的5秒 这样做 应该能过,poj 1s 就算了
第三重,hash + 反向bfs + 打表, hash 我是用map做的, 同时用map记录表,因为是反向的,所以在询问某一个,要输出答案时,反向输出。
第四重,在想...
第一重代码:
#include <iostream> #include <map> #include <string> #include <queue> using namespace std; const int MAX_ = 10; int f[MAX_][MAX_]; int dir[4][2] = {{-1,0},{1,0},{0,-1},{0,1}}; char ss[4] = {'u','d','l','r'}; struct point { int init[MAX_][MAX_]; int x,y; string str; } s; map<int,bool>mp; void bfs() { queue<point>q; s.str=""; q.push(s); mp.clear(); while(!q.empty()) { point cur, next; cur = q.front(); q.pop(); bool flag = 1; for(int i = 1; i < 4; ++i) { for(int j = 1; j < 4; ++j) { if(cur.init[i][j] != f[i][j]) { flag = 0; break; } } if(!flag)break; } if(flag) { //show(cur); cout<<cur.str<<endl; return; } for(int i = 0; i < 4; ++i) { next.x = cur.x + dir[i][0]; next.y = cur.y + dir[i][1]; if((next.x >= 1 && next.x <= 3) &&(next.y >= 1 && next.y <= 3)) { for(int k = 1; k < 4; ++k) { for(int j = 1; j < 4; ++j) { next.init[k][j] = cur.init[k][j]; } } swap(next.init[next.x][next.y],next.init[cur.x][cur.y]); next.str = cur.str; next.str.push_back(ss[i]); int cnt = 0; for(int k =1; k < 4; ++k) { for(int j = 1; j < 4; ++j) { cnt = cnt*10 + next.init[k][j]; } } if(mp.find(cnt) == mp.end()) { mp[cnt] = 1; q.push(next); } } } } cout<<"unsolvable"<<endl; } int main() { char c; int sx,sy; while(cin>>c) { c == 'x'?s.init[1][1] = 0:s.init[1][1] = c- '0'; for(int i = 2; i < 4; ++i) { cin>> c; c == 'x'?s.init[1][i] = 0:s.init[1][i] = c - '0'; } for(int i = 2; i < 4; ++i) { for(int j = 1; j < 4; ++ j) { cin>>c; c == 'x'?s.init[i][j] = 0:s.init[i][j] = c - '0'; } } for(int i = 1; i < 4; ++i) { for(int j = 1; j < 4; ++ j) { if(s.init[i][j] == 0) { s.x = i, s.y = j; } } } int cnt = 1; for(int i = 1; i < 4; ++i) { for(int j = 1; j < 4; ++j) { f[i][j] = cnt++; cnt %= 9; } } bfs(); } return 0; }
第二重,懒得想了,
直接第三重:
#include <iostream> #include <map> #include <string> #include <queue> #include <algorithm> using namespace std; const int MAX_ = 10; int f[MAX_][MAX_]; int dir[4][2] = {{-1,0},{1,0},{0,-1},{0,1}}; char ss[4] = {'d','u','r','l'}; struct point { int init[MAX_][MAX_]; int x,y; string str; } s; map<int,string>mp; void bfs() { queue<point>q; s.str=""; q.push(s); mp.clear(); while(!q.empty()) { point cur, next; cur = q.front(); q.pop(); for(int i = 0; i < 4; ++i) { next.x = cur.x + dir[i][0]; next.y = cur.y + dir[i][1]; if((next.x >= 1 && next.x <= 3) &&(next.y >= 1 && next.y <= 3)) { for(int k = 1; k < 4; ++k) { for(int j = 1; j < 4; ++j) { next.init[k][j] = cur.init[k][j]; } } swap(next.init[next.x][next.y],next.init[cur.x][cur.y]); next.str = cur.str; next.str.push_back(ss[i]); int cnt = 0; for(int k =1; k < 4; ++k) { for(int j = 1; j < 4; ++j) { cnt = cnt*10 + next.init[k][j]; } } if(mp.find(cnt) == mp.end()) { mp[cnt] = next.str; q.push(next); } } } } } int main() { char c; int sx,sy; int cnt = 1; for(int i = 1; i < 4; ++i) { for(int j = 1; j < 4; ++j) { s.init[i][j] = cnt++; cnt %= 9; } } s.x = 3, s.y = 3; bfs(); while(cin>>c) { c == 'x'?f[1][1] = 0:f[1][1] = c- '0'; for(int i = 2; i < 4; ++i) { cin>> c; c == 'x'?f[1][i] = 0:f[1][i] = c - '0'; } for(int i = 2; i < 4; ++i) { for(int j = 1; j < 4; ++ j) { cin>>c; c == 'x'?f[i][j] = 0:f[i][j] = c - '0'; } } int cnt = 0; for(int k =1; k < 4; ++k) { for(int j = 1; j < 4; ++j) { cnt = cnt*10 + f[k][j]; } } if(mp.find(cnt) == mp.end()) { cout<<"unsolvable"<<endl; } else { reverse(mp[cnt].begin(),mp[cnt].end()); cout<<mp[cnt]<<endl; } } return 0; }