八数码
#include <iostream>
#include <queue>
#include <cstring>
#include <cstdio>
#include <conio.h>
using namespace std;
struct node {
int mp[9];
int x,y,dis,value;
int getValue(){
int v = 0;
for(int i = 0; i < 9; i++)
v = v * 10 + mp[i];
this->value = v;
return v;
}
};
const int N = 4e5;
const int mod = 8e5;
//变量
node goal,start,state[N];
queue <node> q;
int dx[4] = {1,-1,0,0},dy[4] = {0,0,1,-1};
int cnt,hs[2 * N];
bool st[2 * N];
int find (int value){//找出这个状态对应的hash值,x 表示状态的 value
int k = value % mod;
while(hs[k] != -1 && hs[k] != value){
// cout << " yes" << endl;
k++;
if(k == mod) k = 0;
}
return k;
}
void bfs(){
state[cnt++] = goal;
q.push(goal);
hs[find(goal.value)] = goal.value;
st[find(goal.value)] = 1;
while(q.size()){
node tt = q.front();
q.pop();
// cout << " yes" << endl;
for(int i = 0; i < 4; i++){
int xx = tt.x + dx[i],yy = tt.y + dy[i];
if(xx >= 0 && xx < 3 && yy >= 0 && yy < 3){
node tp = tt;
swap(tp.mp[tt.x * 3 + tt.y],tp.mp[xx * 3 + yy]);
tp.getValue();
tp.x = xx,tp.y = yy;
tp.dis = tt.dis + 1;
if(!st[find(tp.value)]){
hs[find(tp.value)] = tp.value;
st[find(tp.value)] = 1;
state[cnt++] = tp;
q.push(tp);
}
}
}
}
}
void init(){
memset(hs,-1,sizeof hs);
goal.mp[0] = 1,goal.mp[1] = 2,goal.mp[2] = 3;
goal.mp[3] = 8,goal.mp[4] = 0,goal.mp[5] = 4;
goal.mp[6] = 7 ,goal.mp[7] = 6,goal.mp[8] = 5;
goal.x = goal.y = 1,goal.value = 123804765;
goal.dis = 0;
bfs();
}
void print(bool flag){
if(!flag){
puts("这种状态是无法到达目的状态的");
exit(0);
}
char sp[10];
for(int i = 0; i < 9; i++)
if(start.mp[i] == 0) sp[i] = ' ';
else sp[i] = '0' + start.mp[i];
printf("--------------------------------\n");
printf("| %c %c %c | %d %d %d |\n",sp[0],sp[1],sp[2],1,2,3);
printf("| %c %c %c | %d %d %d |\n",sp[3],sp[4],sp[5],8,0,4);
printf("| %c %c %c | %d %d %d | dis:%d步\n",sp[6],sp[7],sp[8],7,6,5,start.dis);
printf("--------------------------------\n");
}
void opera (char op){
int xx,yy;
xx = start.x ,yy = start.y;
if(op == 'w'){
if(xx > 0) xx--;
}
else if(op == 's'){
if(xx < 2) xx ++;
}
else if(op == 'a'){
if(yy > 0) yy--;
}
else {
if(yy < 2) yy++;
}
swap(start.mp[start.x * 3 + start.y],start.mp[xx * 3 + yy]);
start.x = xx,start.y = yy;
start.getValue();
bool flag = 0;
for(int i = 0; i < cnt; i++){
if(start.value == state[i].value){
start.dis = state[i].dis;
flag = 1;
break;
}
}
print(flag);
}
int main()
{
init();
cout << "请输入初始状态:" << endl;
for(int i = 0; i < 9; i++) {
cin >> start.mp[i];
if(start.mp[i] == 0) start.x = i / 3, start.y = i % 3;
}
cout << "请输入w s a d 控制小空格上下左右移动,使其达到目标状态" << endl;
while(start.value != goal.value){
char op = getch();
opera(op);
}
cout << "你赢了!" << endl;
return 0;
}