POJ1077(八数码)

Eight

Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 30127   Accepted: 13108   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

POJ上的数据比较水,杭电服务器维护,明天到杭电上提交试试
  1 //2016.8.25
  2 #include<iostream>
  3 #include<cstdio>
  4 #include<algorithm>
  5 #include<map>
  6
  7 using namespace std;
  8
  9 int a[10][10], b[10], d[1000], sx, sy, deep;
 10 bool ok;
 11 map<int, bool> vis;
 12 char dir[4] = {‘u‘, ‘d‘, ‘l‘, ‘r‘};
 13 int dx[4] = {-1, 1, 0, 0};
 14 int dy[4] = {0, 0, -1, 1};
 15
 16 bool solve()//求逆序对判断是否有解
 17 {
 18     int cnt = 0;
 19     for(int i = 1; i <= 9; i++)
 20       for(int j = 0; j < i; j++)
 21         if(b[i] && b[j]>b[i])
 22           cnt++;
 23     return !(cnt%2);
 24 }
 25
 26 int Astar()
 27 {
 28     int h = 0;
 29     for(int i = 1; i <= 3; i++)
 30         for(int j = 1; j <= 3; j++)
 31             if(a[i][j]!=0)
 32             {
 33                 int nx = (a[i][j]-1)/3;
 34                 int ny = (a[i][j]-1)%3;
 35                 h += (abs(i-nx-1)+abs(j-ny-1));
 36             }
 37     return h;
 38 }
 39
 40 int toInt()//把矩阵转换为int型数字
 41 {
 42     int res = 0;
 43     for(int i = 1; i <= 3; i++)
 44       for(int j = 1; j <= 3; j++)
 45         res = res*10+a[i][j];
 46     return res;
 47 }
 48
 49 void IDAstar(int x, int y, int step)
 50 {
 51     if(ok)return ;
 52     int h = Astar();
 53     if(!h && toInt()==123456780)//找到答案
 54     {
 55         for(int i = 0; i < step; i++)
 56             cout<<dir[d[i]];
 57         cout<<endl;
 58         ok = 1;
 59         return ;
 60     }
 61     if(step+h>deep)return ;
 62     int now = toInt();
 63     if(vis[now])return ;
 64     vis[now] = true;
 65     for(int i = 0; i < 4; i++)
 66     {
 67         int nx = x+dx[i];
 68         int ny = y+dy[i];
 69         if(nx>=1&&nx<=3&&ny>=1&&ny<=3)
 70         {
 71             d[step] = i;
 72             swap(a[x][y], a[nx][ny]);
 73             IDAstar(nx, ny, step+1);
 74             swap(a[x][y], a[nx][ny]);
 75             d[step] = 0;
 76         }
 77     }
 78     return;
 79 }
 80
 81 int main()
 82 {
 83     char ch;
 84     while(cin >> ch)
 85     {
 86         ok = false;
 87         deep = 0;
 88         int cnt = 0;
 89         for(int i = 1; i <= 3; i++)
 90         {
 91             for(int j = 1; j <= 3; j++)
 92             {
 93                 if(i==1&&j==1);
 94                 else cin >> ch;
 95                 if(ch == ‘x‘)
 96                 {
 97                     a[i][j] = 0;
 98                     sx = i;
 99                     sy = j;
100                 }else
101                   a[i][j] = ch - ‘0‘;
102                 b[cnt++] = a[i][j];
103             }
104         }
105         if(!solve())
106         {
107             cout<<"unsolvable"<<endl;
108             continue;
109         }
110         while(!ok)
111         {
112             vis.clear();
113             IDAstar(sx, sy, 0);
114             deep++;
115         }
116     }
117
118     return 0;
119 }
时间: 2024-10-27 00:28:37

POJ1077(八数码)的相关文章

ACM/ICPC算法训练 之 BFS-广搜进阶-八数码(经典)(POJ1077+HDU1043)

八数码问题也称为九宫问题.(本想查查历史,结果发现居然没有词条= =,所谓的历史也就不了了之了) 在3×3的棋盘,摆有八个棋子,每个棋子上标有1至8的某一数字,不同棋子上标的数字不相同.棋盘上还有一个空格,与空格相邻的棋子可以移到空格中.要求解决的问题是: 给出一个初始状态和一个目标状态,找出一种从初始转变成目标状态的移动棋子步数最少的移动步骤. 所谓问题的一个状态就是棋子在棋盘上的一种摆法.棋子移动后,状态就会发生改变.解八数码问题就是找出从初状态到目标状态所经过的一系列中间状态.八数码问题一

1225 八数码难题

1225 八数码难题 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题解 查看运行结果 题目描述 Description Yours和zero在研究A*启发式算法.拿到一道经典的A*问题,但是他们不会做,请你帮他们.问题描述 在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字.棋盘中留有一个空格,空格用0来表示.空格周围的棋子可以移到空格中.要求解的问题是:给出一种初始布局(初始状态)和目标布局(为了使题目简单,设目标状态为123804765

HDU 1043 Eight八数码解题思路(bfs+hash 打表 IDA* 等)

题目链接 https://vjudge.net/problem/HDU-1043 经典的八数码问题,学过算法的老哥都会拿它练搜索 题意: 给出每行一组的数据,每组数据代表3*3的八数码表,要求程序复原为初始状态 思路: 参加网站比赛时拿到此题目,因为之前写过八数码问题,心中暗喜,于是写出一套暴力bfs+hash,结果TLE呵呵 思路一:bfs+hash(TLE) 1 #include <cstdio> 2 #include <cstring> 3 #include <queu

洛谷【P1379】八数码难题

P1379 八数码难题 题目描述 在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字.棋盘中留有一个空格,空格用0来表示.空格周围的棋子可以移到空格中.要求解的问题是:给出一种初始布局(初始状态)和目标布局(为了使题目简单,设目标状态为123804765),找到一种最少步骤的移动方法,实现从初始布局到目标布局的转变. 输入输出格式 输入格式: 输入初试状态,一行九个数字,空格用0表示 输出格式: 只有一行,该行只有一个数字,表示从初始状态到目标状态需要的最少移动次数(测试数据中无特殊

八数码三种用时差距极大的写法

进化史,一种比一种长,一种比一种快.不过第三种似乎还不是最终形态. 第一种,傻逼级迭代加深. 去年十一月写的,那时候刚刚学迭代加深,敲了一个钟头才敲完,codevs上直接过,就没太管,觉得这是个水题.实际上呢,看后文. 1 #include<algorithm> 2 #include<iostream> 3 #include<cstring> 4 #include<cstdio> 5 using namespace std; 6 int sx,sy,lim,

八数码的八境界 [转载]

八数码的八境界   研究经典问题,空说不好,我们拿出一个实际的题目来演绎.八数码问题在北大在线测评系统中有一个对应的题,题目描述如下: Eight Time Limit: 1000MS    Memory Limit: 65536K  Special Judge Description The 15-puzzle has been aroundfor over 100 years; even if you don't know it by that name, you've seen it. I

【转】八数码问题及A*算法

一.八数码问题八数码问题也称为九宫问题.在3×3的棋盘,摆有八个棋子,每个棋子上标有1至8的某一数字,不同棋子上标的数字不相同.棋盘上还有一个空格,与空格相邻的棋子可以移到空格中.要求解决的问题是:给出一个初始状态和一个目标状态,找出一种从初始转变成目标状态的移动棋子步数最少的移动步骤.所谓问题的一个状态就是棋子在棋盘上的一种摆法.棋子移动后,状态就会发生改变.解八数码问题实际上就是找出从初始状态到达目标状态所经过的一系列中间过渡状态.八数码问题一般使用搜索法来解.搜索法有广度优先搜索法.深度优

HDU 3567 Eight II(八数码 II)

p.MsoNormal { margin: 0pt; margin-bottom: .0001pt; text-align: justify; font-family: Calibri; font-size: 10.5000pt } h1 { margin-top: 5.0000pt; margin-bottom: 5.0000pt; text-align: center; font-family: 宋体; color: rgb(26,92,200); font-weight: bold; fo

cdoj 1380 Xiper的奇妙历险(2) [八数码问题 bfs + 预处理]

快要NOIP 2016 了,现在已经停课集训了.计划用10天来复习以前学习过的所有内容.首先就是搜索. 八数码是一道很经典的搜索题,普通的bfs就可求出.为了优化效率,我曾经用过康托展开来优化空间,甚至还用过A*来优化时间.不过这道题懒得写了,就一个普普通通的bfs,再加上一个stl 的map就水过了. 首先题目要求有多达10000组数据,依次搜索肯定是不行的,我试过用A*来写,第2组数据就会T掉,所以我们考虑用一个预处理.从末尾状态搜索所有可行的状态,并用一个map来存储答案.然后就很好写了.