ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

[AcWing 179] 八数码

2022-08-07 14:03:45  阅读:129  来源: 互联网

标签:end string int res start 数码 heap 179 AcWing


image
image

A* 算法


点击查看代码
#include<bits/stdc++.h>

using namespace std;

typedef long long LL;
typedef pair<int,string> PIS;

const int N = 1e6 + 10;

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

int f(string s)
{
    int res = 0;
    for (int i = 0; i < s.size(); i ++)
        if (s[i] != 'x') {
            int t = s[i] - '1';
            res += abs(i / 3 - t / 3) + abs(i % 3 - t % 3);
        }
    return res;
}

string bfs()
{
    string end = "12345678x";
    unordered_map<string, int> d;
    unordered_map<string, pair<string,char>> pre;
    priority_queue<PIS, vector<PIS>, greater<PIS>> heap;
    
    heap.push({f(start), start});
    d[start] = 0;

    while (heap.size()) {
        auto t = heap.top();
        heap.pop();
        string s = t.second;
        if (s == end)
            break;
        int step = d[s];
        int p = s.find('x');
        int x = p / 3, y = p % 3;
        string pre_s = s;
        for (int i = 0; i < 4; i ++) {
            int a = x + dx[i], b = y + dy[i];
            if (a < 0 || a >= 3 || b < 0 || b >= 3)
                continue;
            swap(s[x * 3 + y], s[a * 3 + b]);
            if (!d.count(s) || d[s] > step + 1) {
                d[s] = step + 1;
                pre[s] = {pre_s, op[i]};
                heap.push({d[s] + f(s), s});
            }
            swap(s[x * 3 + y], s[a * 3 + b]);
        }
    }
    string res;
    while (end != start) {
        res += pre[end].second;
        end = pre[end].first;
    }
    reverse(res.begin(), res.end());
    return res;
}

void solve()
{
    char c;
    while (cin >> c) {
        start += c;
    }
    int t = 0;
    for (int i = 0; i < start.size(); i ++)
        for (int j = i + 1; j < start.size(); j ++) {
            int s1 = start[i], s2 = start[j];
            if (s1 == 'x' || s2 == 'x')
                continue;
            if (s1 > s2)
                t ++;
        }
    if (t % 2)
        cout << "unsolvable" << endl;
    else
        cout << bfs() << endl;
}

signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    solve();

    return 0;
}

  1. 八数码问题
    设 \(s\) 为输入字符串去掉 \(x\) 后的字符串
    ① 当 \(s\) 的逆序对个数为奇数时,无解
    ② 当 \(s\) 的逆序对个数为偶数时,有解
  2. 估价函数
    \(1\) ~ \(8\) 每个数和最终位置的曼哈顿距离之和,这个距离之和小于真实的移动次数,满足 \(A^{*}\) 算法估价值小于真实值的条件
  3. 在原来八数码问题的基础上,用 \(A^{*}\) 算法缩小搜索范围,并且记录方案

标签:end,string,int,res,start,数码,heap,179,AcWing
来源: https://www.cnblogs.com/wKingYu/p/16558944.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有