首页 > 其他分享 >179. 八数码

179. 八数码

时间:2023-10-23 19:24:03浏览次数:20  
标签:string int ed move tmpc st 数码 179

179.八数码

 

估价函数:曼哈顿距离

 

#include <iostream>
#include <cstring>
#include <unordered_map>
#include <sstream>
#include <queue>
#include <vector>
#include <algorithm>

using namespace std;
typedef pair<int, string> PIS;

const int N = 105;

unordered_map<string, int> dist;
unordered_map<string, pair<char, string>> from;

string st, ed = "12345678x";

inline bool check(char t);

inline int e_value(string s)
{
    int res = 0;
    for (int i = 0; i < 9; i++)
    {
        if (s[i] == 'x')
            continue;
        int nx = i / 3, ny = i % 3;
        int rs = s[i] - '1'; // 因为下标从0开始,所以这里的rs也要从0开始
        int fx = rs / 3, fy = rs % 3;
        res += abs(nx - fx) + abs(ny - fy);
    }
    return res;
}

inline bool check(char t)
{
    if (t == 'x')
        return 1;
    if (isdigit(t))
        return 1;
    return 0;
}

void bfs(string st, string ed)
{
    int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};
    char dway[4] = {'u', 'r', 'd', 'l'};
    priority_queue<PIS, vector<PIS>, greater<PIS>> q;
    q.push({e_value(st), st});
    dist[st] = 0;
    while (q.size())
    {
        auto tmp = q.top();
        q.pop();
        string tmpc = tmp.second;
        if (tmpc == ed)
        {
            return;
        }
        int xpos;
        int dis = dist[tmpc];
        for (int i = 0; i < 9; i++)
            if (tmpc[i] == 'x')
            {
                xpos = i;
                break;
            }
        int nx = xpos / 3, ny = xpos % 3;
        for (int i = 0; i < 4; i++)
        {
            int fx = nx + dx[i], fy = ny + dy[i];
            if (fx < 0 || fx >= 3 || fy < 0 || fy >= 3)
                continue;
            int fpos = fx * 3 + fy;
            swap(tmpc[xpos], tmpc[fpos]);
            string after_move = tmpc;
            swap(tmpc[xpos], tmpc[fpos]);
            int dis_new = dis + 1;
            if (!dist.count(after_move) || dist[after_move] > dis_new)
            {

                q.push({e_value(after_move) + dis_new, after_move});
                dist[after_move] = dis_new;
                from[after_move] = {dway[i], tmpc};
            }
        }
    }
}

int main()
{
    string input;
    getline(cin, input);
    for (int i = 0; input[i]; i++) // 一开始忘记写i=0,虽然本地可以跑通,但是acwing上一直SF
    {
        if (check(input[i]))
            st += input[i];
    }
    int cnt = 0;
    for (int i = 0; i < 9; i++)
    {
        if (st[i] == 'x')
            continue;
        for (int j = i + 1; j < 9; j++)
            if (st[j] < st[i])
                cnt++;
    }
    if (cnt & 1)
    {
        puts("unsolvable");
    }
    else
    {
        bfs(st, ed);

        string ansv;
        while (ed != st)
        {
            ansv += from[ed].first;
            ed = from[ed].second;
        }
        reverse(ansv.begin(), ansv.end());
        cout << ansv << endl;
    }
    return 0;
}

 

标签:string,int,ed,move,tmpc,st,数码,179
From: https://www.cnblogs.com/smartljy/p/17783246.html

相关文章

  • Educational Codeforces Round 144(CF1796 D~E) 题解
    D.MaximumSubarray题目链接十分钟秒了一道*2000,非常爽,但是个人感觉确实非常简单。下面令\(b_i=a_{i}-x\),\(b_i'=a_i+x\)。因为\(k<=20\),因此考虑一个复杂度与\(k\)相关的做法。不妨dp:设\(f_{i,j,0/1}\)表示考虑了前\(i\)个数,对\(j\)个数加上了\(x\),第\(i\)......
  • [题解] CF1790E - XOR Tree
    CF1790E-XORTree题意给定一颗无根树,在可以改变任意一个点的点权操作基础上,让树上任意简单路径的异或和不为\(0\),问最少需要多少次操作。思路假设某个点为根,设\(pre_x\)为\(x\)点到根的树上前缀异或和,\(a_x\)为\(x\)的点权,则\(x\)和\(y\)之间简单路径的异或和......
  • Programming abstractions in C阅读笔记:p179-p180
    《ProgrammingAbstractionsInC》学习第60天,p179-p180总结。一、技术总结1.palindrome(回文)(1)包含单个字符的字符串(如"a"),或者空字符串(如"")也是回文。(2)示例:“level”、"noon"。2.predicatefunction(1)predicate的意思pre-("forth")+*deik-("show"),“t......
  • Dream Dance (179 CD 无损flac)
    80年代电音舞曲的精华,百听不厌,听听鼻祖电音,迷幻的迪斯科,定会爱上它的链接:https://pan.baidu.com/s/1mdx2tQFmXie13JYi7cwiiA提取码:mybn......
  • CF1796D 做题笔记
    题目链接一眼题,但这个$k$迷惑了我很久。由于我初始的思路没考虑$x<0$,所以我们先默认$x>0$。考虑任意一个是最优答案的最大子段和,如果它的长度$<k$那么它的每个元素一定都加上了$x$,如果它的长度$>k$,那么它的$k$个元素一定加上了$x$,剩余的一定减去了$x$。小于$k$......
  • 1793_树莓派杂志第一期MagPi01阅读
    GreyZhang/little_bits_of_raspberry_pi:myhackingtripaboutraspberrypi.(github.com)        给自己的产品起一个好听的名称,我觉得这个是国外的企业中很好的一种文化。这里提到的苹果、黑莓等全都是一系列的水果。树莓派也有这样的风格,但是其实树莓派的名字由来还......
  • 1790_给通过USB连接到树莓派的NTFS硬盘设置固定的挂载名称
            全部学习汇总:GreyZhang/little_bits_of_raspberry_pi:myhackingtripaboutraspberrypi.(github.com)        我用过好几个树莓派形式的单板电脑,但是遇到过磁盘挂载位置不确定的时候。有些甚至不会自动挂载。这些行为跟对应的OS的行为是相关的,而我......
  • 1791_树莓派bash入门杂志_Essentials_Bash_v1
            全部学习汇总:GreyZhang/little_bits_of_raspberry_pi:myhackingtripaboutraspberrypi.(github.com)        拿到一份树莓派早期的宣传电子杂志资料,看了一下感觉还是有一些帮助。针对里面多少有一些共鸣的地方,做一个简单的整理。        ......
  • LORA射频开关芯片ATR5179 VS PE4259 单刀双掷开关单芯片
    PE4259UltraCMOS@射频开关是专为涵盖10兆赫-3000兆赫的广泛应用。这款反射式开关集成了具有低电压的板上CMOS控制逻辑CMOS兼容的控制接口,并可将使用单引脚或互补引脚控制控制的输入端。ATR5179是一款采用pHEMTGaAs工艺制作的单刀双掷开关单芯片,芯片内部电路结构简单,该芯片的推......
  • 51nod 3179 绝世好题
    原题确实是绝世好题朴素\(dp\)问题非常simple,考虑优化想尽数据结构无从下手?既然二进制考虑按位贪心发现对于\(a_i\)所有为\(1\)的位上一位只要有一位为\(1\)即可,剩下的显然越靠后越好因此我们设\(dp_{i,j}\)表示前\(i\)个数,其中最后一个被选的数第\(j\)位为......