百练#1077Eight
作者:互联网
描述
八数码问题,目标固定为123456780,输出路径。
输入
You will receive a description of a configuration of the 8 puzzle. The description is just a list of the tiles in their initial positions, with the rows listed from top to bottom, and the tiles listed from left to right within a row, where the tiles are represented by numbers 1 to 8, plus ‘x’. For example, this puzzle
1 2 3
x 4 6
7 5 8
is described by this list:
1 2 3 x 4 6 7 5 8
输出
You will print to standard output either the word ``unsolvable’’, if the puzzle has no solution, or a string consisting entirely of the letters ‘r’, ‘l’, ‘u’ and ‘d’ that describes a series of moves that produce a solution. The string should include no spaces and start at the beginning of the line.
样例输入
2 3 4 1 5 x 7 6 8
样例输出
ullddrurdllurdruldr
#include<iostream>
#include<cstring>
using namespace std;
const int MAX = 1000000;
const int d[4][2] = {{0,-1},{-1,0},{0,1},{1,0}};
int st[MAX][9];//宽搜的队列,保存的是图的状态
int dist[MAX],goal[9] = {1,2,3,4,5,6,7,8,0};
int head[MAX],nnext[MAX];//链地址法的哈希表
int fa[MAX];
int Hash(int s){//地址映射,将序列转换成整数再哈希
int t = 0;
for(int i = 0;i < 9; ++i)
t = t * 10 + st[s][i];
return t % MAX;
}
int Insert(int s){//哈希表判断是否有重复
int k = Hash(s);
int v = head[k];
while(v){
if(memcmp(st[s],st[v],sizeof(st[s])) == 0)
return 0;
v = nnext[v];
}
nnext[s] = head[k];
head[k] = s;
return 1;
}
int bfs(){//八数码问题就是把状态作为各个节点然后使用宽搜获得最短路径,此题答案不唯一。
int i;
memset(head,0,sizeof(head));
memset(dist,0,sizeof(dist));//初始化步长数组(紫书)
int front = 1,rear = 2;
while(rear > front){
int s = front;
if(memcmp(st[s],goal,sizeof(goal)) == 0)
return s;
for(i = 0;i < 9; ++i)
if(!st[s][i])
break;
int z = i;
int x = z / 3,y = z % 3;
for(int i = 0;i < 4; ++i){
int nx = x + d[i][0];
int ny = y + d[i][1];
int nz = nx * 3 + ny;
if(nx >= 0 && nx < 3 && ny >= 0 && ny < 3){
memcpy(st[rear],st[s],sizeof(st[s]));
st[rear][z] = st[s][nz];
st[rear][nz] = st[s][z];
dist[rear] = dist[s] + 1;
fa[rear] = s;//记录父节点,便于输出路径
if(Insert(rear)){
rear++;
}
}
}
++front;
}
return 0;
}
char step(int s){//获得移动方式
int t = fa[s];
if(!fa[s])
return '0';
int i;
for(i = 0;i < 9; ++i){
if(!st[s][i])
break;
}
int x = i / 3,y = i % 3;
for(i = 0;i < 9; ++i){
if(!st[t][i])
break;
}
int nx = i / 3,ny = i % 3;
int dx = x - nx,dy = y - ny;
if(dx == 0 && dy == -1)
return 'l';
if(dx == -1 && dy == 0)
return 'u';
if(dx == 0 && dy == 1)
return 'r';
if(dx == 1 && dy == 0)
return 'd';
}
int main(){
int i;
char c;
for(i = 0;i < 9; ++i){
cin >> c;
if(c == 'x')
c = '0';
st[1][i] = c - '0';
}
memset(fa,0,sizeof(fa));
int ans = bfs();
int cnt = 0;
char t,temp[50];
if(ans){
while(1){
t = step(ans);
if(t == '0')
break;
temp[cnt++] = t;
ans = fa[ans];
}
for(i = cnt - 1;i >= 0; --i)
printf("%c",temp[i]);
printf("\n");
}
else
printf("unsolvable\n");
return 0;
}
百练的G++编译器实在是太智能了,next也不能作为数组名。
Tech_hysteria 发布了41 篇原创文章 · 获赞 0 · 访问量 532 私信 关注标签:return,int,MAX,st,++,百练,rear,1077Eight 来源: https://blog.csdn.net/weixin_38894974/article/details/104555541