# POJ-1077 HDU-1043 Eight(单广,双广,启发式搜索)

Eight
 Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 29854 Accepted: 12989 Special Judge

Description

The 15-puzzle has been around for over 100 years; even if you don't know it by that name, you've seen it. It is constructed with 15 sliding tiles, each with a number from 1 to 15 on it, and all packed into a 4 by 4 frame with one tile missing. Let's call the missing tile 'x'; the object of the puzzle is to arrange the tiles so that they are ordered as:
 1  2  3  4

5  6  7  8

9 10 11 12

13 14 15  x 

where the only legal operation is to exchange 'x' with one of the tiles with which it shares an edge. As an example, the following sequence of moves solves a slightly scrambled puzzle:
 1  2  3  4    1  2  3  4    1  2  3  4    1  2  3  4

5  6  7  8    5  6  7  8    5  6  7  8    5  6  7  8

9  x 10 12    9 10  x 12    9 10 11 12    9 10 11 12

13 14 11 15   13 14 11 15   13 14  x 15   13 14 15  x

r->           d->           r-> 

The letters in the previous row indicate which neighbor of the 'x' tile is swapped with the 'x' tile at each step; legal values are 'r','l','u' and 'd', for right, left, up, and down, respectively.

Not all puzzles can be solved; in 1870, a man named Sam Loyd was famous for distributing an unsolvable version of the puzzle, and
frustrating many people. In fact, all you have to do to make a regular puzzle into an unsolvable one is to swap two tiles (not counting the missing 'x' tile, of course).

In this problem, you will write a program for solving the less well-known 8-puzzle, composed of tiles on a three by three
arrangement.

Input

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

Output

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.

Sample Input

 2  3  4  1  5  x  7  6  8

Sample Output

ullddrurdllurdruldr

1.广搜，打表

#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>
#define maxn 400005
using namespace std;

struct Node{
char p[10];
int x, y, f;
char ch;
}node[maxn];
int vis[maxn], d[10];
int dir[4][2] = {1, 0, -1, 0, 0, 1, 0, -1};
int k[4] = {'u', 'd', 'l', 'r'}, m = 1;
int cal(char *p){
int ans = 0;
for(int i = 0; i < 9; i++){
int h = 0;
for(int j = i+1; j < 9; j++)
if(p[i] > p[j])
h++;
ans += h * d[8-i];
}
return ans;
}
void Bfs(){

char t[10] = "123456780";
vis[cal(t)] = 1;
strcpy(node[1].p, t);
node[1].x = 2, node[1].y = 2;
node[1].f = -1;
queue<int> q;
q.push(1);
while(!q.empty()){
int h = q.front();
q.pop();
for(int i = 0; i < 4; i++){
int x = node[h].x + dir[i][0];
int y = node[h].y + dir[i][1];
if(x >= 0 && x < 3 && y >= 0 && y < 3){
strcpy(t, node[h].p);
swap(t[node[h].x*3+node[h].y], t[x*3+y]);
int e = cal(t);
if(vis[e] == 0){
++m;
vis[e] = m;
strcpy(node[m].p, t);
node[m].x = x;
node[m].y = y;
node[m].ch = k[i];
node[m].f = h;
q.push(m);
}
}
}
}
}
void print(int e){

vector<char> v;
while(node[e].f != -1){
v.push_back(node[e].ch);
e = node[e].f;
}
for(int i = 0; i < v.size(); i++)
putchar(v[i]);
puts("");
}
int main(){

//	freopen("in.txt", "r", stdin);
d[1] = 1;
for(int i = 2; i <= 9; i++)
d[i] = d[i-1] * i;
Bfs();
char g[50];
while(gets(g)){

int e = 0;
for(int i = 0; g[i]; i++){
if(g[i] != ' ')
g[e++] = g[i];
if(g[i] == 'x')
g[e-1] = '0';
}
e = cal(g);
if(vis[e])
print(vis[e]);
else
puts("unsolvable");
}
return 0;
}


2.双向广度优先搜索(hdu上904ms)

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
#define maxn 400005
using namespace std;

struct Node{
char p[10];
char ch;
int f, x, y;
}node[maxn];
int vis[maxn];
int dir[4][2] = {0, 1, 0, -1, 1, 0, -1, 0};
char k[2][4] = {{'r', 'l', 'd', 'u'}, {'l', 'r', 'u', 'd'}};
int d[10], m;
queue<int> q[2];
int cal(const char *p){

int ans = 0;
for(int i = 0; i < 9; i++){
int cnt = 0;
for(int j = i+1; j < 9; j++){
if(p[i] > p[j])
cnt++;
}
ans += d[8-i] * cnt;
}
return ans;
}
void Init(){

d[1] = 1;
for(int i = 2; i < 9; i++)
d[i] = d[i-1] * i;
while(!q[0].empty())
q[0].pop();
while(!q[1].empty())
q[1].pop();
memset(vis, 0, sizeof(vis));
const char *p = "123456780";
strcpy(node[2].p, p);
node[2].x = 2, node[2].y = 2, node[2].f = -1;
vis[cal(p)] = -2;
}
bool judge(char *p){

int cnt = 0;
for(int i = 0; i < 9; i++)
for(int j = i+1; j < 9; j++){
if(p[i] != '0' && p[j] != '0' && p[i] > p[j])
cnt++;
}
if(cnt&1)return false;
return true;
}
void print1(int e){

if(node[e].f != -1){
print1(node[e].f);
putchar(node[e].ch);
}
}
void print2(int e){

while(node[e].f != -1){
putchar(node[e].ch);
e = node[e].f;
}
puts("");
}
bool BFS(queue<int> &q, char *kk, int u){

char p[10];
int t = q.front();
q.pop();
for(int i = 0; i < 4; i++){
int x = node[t].x + dir[i][0];
int y = node[t].y + dir[i][1];
if(x >= 0 && x < 3 && y >= 0 && y < 3){
strcpy(p, node[t].p);
swap(p[node[t].x*3+node[t].y], p[x*3+y]);
int u1 = cal(p);
if(vis[u1] == 0){
++m;
node[m].x = x, node[m].y = y;
node[m].f = t, node[m].ch = kk[i];
strcpy(node[m].p, p);
vis[u1] = m * u;
q.push(m);
}
else if(vis[u1] * u < 0){
if(u == 1){
print1(t);
putchar(kk[i]);
print2(-vis[u1]);
}
else{
print1(vis[u1]);
putchar(kk[i]);
print2(t);
}
return true;
}
}
}
return false;
}
int main(){

// freopen("in.txt", "r", stdin);
char g[50];
while(gets(g)){
Init();
int v = -1;
for(int i = 0; g[i]; i++){
if(g[i] != ' ')
node[1].p[++v] = g[i];
if(g[i] == 'x'){
node[1].p[v] = '0';
node[1].x = v / 3;
node[1].y = v % 3;
}
}
if(!judge(node[1].p)){
puts("unsolvable");
continue;
}
node[1].p[v+1] = 0;
node[1].f = -1;
vis[cal(node[1].p)] = 1;
q[0].push(1);
q[1].push(2);
int sign = 0;
m = 2;
while(!q[0].empty() && !q[1].empty()){
int e = 1;
if(q[0].size() < q[1].size())
e = 0;
if(BFS(q[e], k[e], e == 0 ? 1 : -1)){
sign = 1;
break;
}
}
if(sign == 0){
puts("unsolvable");
}
}
return 0;
}  

3.启发式搜索(HDU717ms)

#include <iostream>
#include <algorithm>
#include <queue>
#include <cstdio>
#include <cstring>
#include <vector>
#include <map>
#define maxn 400005
using namespace std;
typedef long long ll;

struct Node{
char p[10];
int pre;
int w, h, x, y;
char ch;
}node[maxn];
struct cmp{
bool operator ()(const int &a, const int &b){
int f1 = node[a].w + node[a].h;
int f2 = node[b].w + node[b].h;
return (f1 == f2 && node[a].h > node[b].h) || f1 > f2;
}
};
int vis[maxn], d[10], e = 46233, m;
int dir[4][2] = {0, 1, 0, -1, 1, 0, -1, 0};
char kk[4] = {'r', 'l', 'd', 'u'};
int cal(const char *p){
int ans = 0;
for(int i = 0; i < 9; i++){
int k = 0;
for(int j = i + 1; j < 9; j++)
if(p[j] < p[i])
k++;
ans += d[8-i] * k;
}
return ans;
}
bool judge(char *p){

int cnt = 0;
for(int i = 0; i < 9; i++)
for(int j = i+1; j < 9; j++)
if(p[i] != '0' && p[j] != '0' && p[i] > p[j])
cnt++;
if(cnt&1)
return false;
return true;
}
int get_h(char *p){

int ans = 0;
for(int i = 0; i < 9; i++){
if(p[i] != '0')
ans += abs(i/3-(p[i]-'0'-1)/3) + abs(i%3-(p[i]-'0'-1)%3);
}
return ans;
}
void print(int v){
if(node[v].pre != -1){
print(node[v].pre);
putchar(node[v].ch);
}
}
bool  Bfs(){
char p[10];
priority_queue<int, vector<int>, cmp> q;
q.push(1);
int c = cal(node[1].p);
if(c == e){
puts("");
return true;
}
vis[c] = 1;
while(!q.empty()){
c = q.top();
q.pop();
for(int i = 0; i < 4; i++){
int x = node[c].x + dir[i][0];
int y = node[c].y + dir[i][1];
if(x >= 0 && x < 3 && y >= 0 && y < 3){
strcpy(p, node[c].p);
swap(p[3*node[c].x+node[c].y], p[3*x+y]);
int v = cal(p);
if(vis[v] == 0){
vis[v] = 1;
++m;
strcpy(node[m].p, p);
node[m].w = node[c].w + 1;
node[m].h = get_h(node[m].p);
node[m].x = x, node[m].y = y;
node[m].pre = c, node[m].ch = kk[i];
q.push(m);
}
if(v == e){
print(m);
puts("");
return true;
}

}
}

}
return false;
}
int main(){

//	freopen("in.txt", "r", stdin);
d[1] = 1;
for(int i = 2; i <= 9; i++)
d[i] = d[i-1] * i;
char g[50];
while(gets(g)){
memset(vis, 0, sizeof(vis));
m = 1;
int k = -1;
for(int i = 0; g[i]; i++){
if(g[i] != ' ')
node[1].p[++k] = g[i];
if(g[i] == 'x'){
node[1].p[k] = '0';
node[1].x = k / 3;
node[1].y = k % 3;
}
}
if(!judge(node[1].p)){
puts("unsolvable");
continue;
}
node[1].p[k+1] = 0;
node[1].pre = -1;
node[1].w = 0, node[1].h = get_h(node[1].p);
if(!Bfs())
puts("unsolvable");
}
return 0;
}


• 点赞
• 评论
• 分享
x

海报分享

扫一扫，分享海报

• 收藏
• 手机看

分享到微信朋友圈

x

扫一扫，手机阅读

• 打赏

打赏

天夏123

你的鼓励将是我创作的最大动力

C币 余额
2C币 4C币 6C币 10C币 20C币 50C币
• 一键三连

点赞Mark关注该博主, 随时了解TA的最新博文
05-23 3326

01-16 298
05-22 296
02-13 5745
01-03 2648
09-17 789
08-21 762
04-25 261
11-06 479