POJ 1077 - Eight(BFS+康托展开)
2017-12-07 16:46
274 查看
上周作业的ProblemA。从这题难度上就可以看出学长出题时的丧病程度了。(希望他看不到)
有名的八数码题啊,要是没有搞懂康托展开,可以先去百度学习一下再看这道题。
传送门:http://poj.org/problem?id=1077
Eight
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 34304 Accepted: 14770 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
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
Source
South Central USA 1998
思路就是,把x视为9或是0,然后将3*3的矩阵拉成一条数列,根据康托展开的原理,每个这样的排列都对应着一个特定的整数,那么这个排列有没有出现过就很容易知道了。由于输入的时候就是一行数列,那么也别费心搞那么麻烦先变3*3又变回来了,直接就保存一行数列,然后保存x的位置就可以了。x在3*3中的位置其实就是x%3, x/3;每次记录好它的康拓展开数,一对比,就出来了。
讲讲这道题的坑点,我一开始老是TLE,以为是算法问题,后面实在找不到了,就把自己的getchar()换成了scanf()结果就过了,这输入数据到底有多少空格啊。。。真是服了
AC代码如下:
有名的八数码题啊,要是没有搞懂康托展开,可以先去百度学习一下再看这道题。
传送门:http://poj.org/problem?id=1077
Eight
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 34304 Accepted: 14770 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
Source
South Central USA 1998
思路就是,把x视为9或是0,然后将3*3的矩阵拉成一条数列,根据康托展开的原理,每个这样的排列都对应着一个特定的整数,那么这个排列有没有出现过就很容易知道了。由于输入的时候就是一行数列,那么也别费心搞那么麻烦先变3*3又变回来了,直接就保存一行数列,然后保存x的位置就可以了。x在3*3中的位置其实就是x%3, x/3;每次记录好它的康拓展开数,一对比,就出来了。
讲讲这道题的坑点,我一开始老是TLE,以为是算法问题,后面实在找不到了,就把自己的getchar()换成了scanf()结果就过了,这输入数据到底有多少空格啊。。。真是服了
AC代码如下:
#include <cstdio> #include <iostream> #include <cstring> #include <queue> #include <string> #define maxn 10 using namespace std; int f[maxn] = { 1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880 }; //int a[maxn]; //string ans; int kt(int *t) { int su = 0; for(int i = 0; i < 9; i++) { int tmp = 0; for(int j = 8; j > i; j--) { if(t[j] < t[i]) tmp++; } su += tmp * f[8-i]; } return su; } int sx, sk; int rch[800000]; struct Node { int x; //x的位置 int t[maxn]; //每次记录的数组 // int p; //字符串的指针 string p; //答案 int k; //康托数 }; int dx[4] = {-1, 1, 0, 0}; int dy[4] = {0, 0, -1, 1}; char di[5] = "udlr"; queue<Node> pa; int main() { char c[20]; // memset(get, 0, sizeof(get)); int tp = 0; Node beg; for(int i = 0; i < 9; i++) { scanf("%s", c); if(c[0] > '0' && c[0] <= '9') beg.t[tp++] = c[0] - '0'; if(c[0] == 'x') { sx = tp; beg.t[tp++] = 0; } } sk = kt(beg.t); beg.x = sx, beg.k = sk; pa.push(beg); rch[beg.k] = 1; while(!pa.empty()) { Node cur = pa.front(); pa.pop(); if(cur.k == 46233) { cout << cur.p << endl; return 0; } int a = cur.x / 3; int b = cur.x % 3; for(int i = 0; i < 4; i++) { int ta = a + dx[i]; int tb = b + dy[i]; if(ta < 0 || ta > 2 || tb < 0 || tb > 2) continue; Node next = cur; next.x = 3 * ta + tb; next.t[cur.x] = next.t[next.x]; next.t[next.x] = 0; next.k = kt(next.t); if(rch[next.k]) continue; if(next.k == 46233) { next.p = cur.p + di[i]; cout << next.p << endl; return 0; } next.p = cur.p + di[i]; rch[next.k] = 1; pa.push(next); } } printf("unsolvable\n"); return 0; }
相关文章推荐
- [POJ]1077 Eight 八数码:康托展开+BFS
- POJ 1077 Eight(BFS八数码问题)
- poj 1077 Eight
- poj 1077--Eight(八数码问题,BFS,A*,全排列的哈希)
- poj - 1077 - Eight
- poj 1077 hdu 1043 Eight 八数码问题 DBFS(双向广度优先搜索)a*算法 康拓展开
- poj 1077 eight
- poj-1077-Eight
- POJ 1077 Eight 八数码问题 A*
- POJ 1077-Eight(BFS+优先队列)
- POJ:1077 Eight(双向BFS+判重)
- POJ-1077 HDU-1043 Eight(单广,双广,启发式搜索)
- POJ1077——Eight
- poj 1077 Eight A*解八数码问题
- POJ 1077 Eight
- HDU 1403 Eight&POJ 1077(康拖,A* ,BFS,双广)
- POJ 1077 Eight(bfs八数码问题)
- POJ 1077 Eight
- HDU 1403 Eight&POJ 1077(康拖,A* ,BFS,双广)
- poj 1077 Eight 八数码问题( 康拓展开+BFS状态压缩)