小记: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;
}