• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
jacklee404
Never Stop!
博客园    首页    新随笔    联系   管理    订阅  订阅
HDU1043-Eight (逆向思维+BFS)

题目

Eight

*Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 46717 Accepted Submission(s): 11657
Special Judge*

Problem 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, several descriptions of configuration of the 8 puzzle. One 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. Do not print a blank line between cases.

Sample Input

2  3  4  1  5  x  7  6  8

Sample Output

ullddrurdllurdruldr

Source

South Central USA 1998 (Sepcial Judge Module By JGShining)

思路 BFS

​ 这道题算是经典例题了,题目要求我们求给定状态到状态\(123456789x\)的最短路径,由于基于八数码的路径是可逆的,那么问题可以转化为从\(12345678x\)到所有状态的路径,那么我们只需要求一次bfs便可以知道所有的状态,这样对于终点状态不可达的路径我们不会进行多余的计算,这样就减少了时间复杂度。

Code

#include <iostream>
#include <cstring>
#include <cmath>
#include <queue>
#include <map>
#include <set>
#include <algorithm>
#include <functional>
#include <utility>
#include <unordered_set>
#include <unordered_map>
#define INF 0x3f3f3f3f
#define IOS ios::sync_with_stdio(false);
#define rep(i, j, k) for(int i = j; i <= k; ++ i)
#define per(i, j, k) for(int i = j; i >= k; -- i)
#define dbg1(a) cout << a << endl;
#define dbg2(a, b) cout << a << " " <<  b << endl;
#define dbg3(a, b, c) cout << a << " " << b << " " << c << endl;
#define pb(x) push_back(x)
#define eb(x) emplace_back(x)
#define all(x) x.begin(), x.end()
#define f first
#define s second
#define lc p<<1
#define rc p<<1|1
using namespace std;
typedef long long LL;
typedef priority_queue<int, vector<int>, greater<int>> S_HEAP;
typedef priority_queue<int> B_HEAP;
typedef pair<string, int> PSI;
typedef pair<int, int> PII;
const int N = 1e6 + 10;

int dx[] = {0, 1, -1, 0}, dy[] = {1, 0, 0, -1};
char act[] = {'l', 'u', 'd', 'r'};


unordered_map<string, int> d;
string ended = "12345678x";


struct node {
        int pre, dir;
        node(int PRE, int DIR) {
                pre = PRE, DIR = dir;
        }
        node(){}
}path[N];

void bfs() {
        int cnt = 0;
        queue<string> q1;
        q1.push(ended);
        path[cnt].pre = -1;
        path[cnt].dir = -1;
        d[ended] = cnt ++;
        while (q1.size()) {
                string t = q1.front(); q1.pop();
                int k = t.find('x');
                int x = k / 3, y = k % 3;
                rep (i, 0, 3) {
                        int tx = x + dx[i], ty = y + dy[i];
                        if (tx >= 0 && tx < 3 && ty >= 0 && ty < 3) {
                                string b = t;
                                swap(b[k], b[tx * 3 + ty]);
                                if (d[b]) 
                                        continue;
                                q1.push(b);
                                path[cnt].pre = d[t];
                                path[cnt].dir = i;
                                d[b] = cnt++;
                        }
                }
        }
}



int main() {
        string start;
        char c;
        bfs();
        while (cin >> c) {
                start.clear();
                start += c;
                for (int i = 1; i < 9; i ++) {
                        cin >> c;
                        start += c;
                }
                if (!d[start]) {
                        puts("unsolvable");
                } else {
                        int k = d[start];
                        while (k != -1) {
                                printf("%c", act[path[k].dir]);
                                k = path[k].pre;
                        }
                        cout << endl;
                }
        }
}
posted on 2023-01-13 15:06  Jack404  阅读(14)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3