首页 > 其他分享 >洛谷P2730 [USACO3.2]魔板 Magic Squares

洛谷P2730 [USACO3.2]魔板 Magic Squares

时间:2022-11-04 17:36:25浏览次数:74  
标签:魔板 kept string 状态 int USACO3.2 swap 操作 Magic

题目链接:点这里

 

一般这种从某种状态转移到目标状态的最短距离,都可以使用BFS来做。

从题目给定的初始状态,依次执行题目给定的三种操作,分别是交换上下两行(操作A)、将最后一列插入到第一列的前面(操作B)、将中间的矩形按照顺时针旋转90度(操作C),将这些操作存到哈希表里,由BFS的特点可知,我们如果到达了目标状态,那么操作次数一定是最小的;在这道题目里,又由于我们是按照字典序来依次执行三个操作的,所以得到的第一个可行解一定是字典序最小的。

题目还要求输出操作的顺序,我们再用一个哈希表存储当前状态是哪个状态经历了一系列操作之后得到的,比如当前状态是12345678,它的上一个状态是56784321,那么当前状态就是由初始状态经过操作A后得到的,如果上一个状态是由初始状态经过*****操作得到的,那么当前状态的操作就是上一个状态加上A,就是*****A。

注意如果初始状态就是基本状态的话,有可能会多输出一个空行,因此特判一下即可。

 

#include <iostream>
#include <unordered_map>
#include <queue>
#include <algorithm>
using namespace std;

const int N = 100010;

string res;

int bfs(string ed) {
    string st = "12345678";
    queue<string> q;
    unordered_map<string, int> h;
    unordered_map<string, string> kept;
    q.push(st);
    h[st] = 0;
    kept[st] = "";
    while(q.size()) {
        auto t = q.front();
        q.pop();
        
        int last = h[t];
        string ls = t;
        if(t == ed) {
            res = kept[t];
            return last;
        }
        
        //操作A
        reverse(t.begin(), t.end());
        if(!h.count(t)) {
            q.push(t), h[t] = last + 1;
            kept[t] = kept[ls] + 'A';
        }
        //变回t,就像‘作案之后还原现场’
        reverse(t.begin(), t.end());
        
        //操作B
        for(int i = 3; i > 0; i--) swap(t[i], t[i - 1]);
        for(int i = 4; i < 7; i++) swap(t[i], t[i + 1]);
        if(!h.count(t)) {
             q.push(t), h[t] = last + 1;
             kept[t] = kept[ls] + 'B';
        }
        //变回t
        for(int i = 0; i < 3; i++) swap(t[i], t[i + 1]);
        for(int i = 7; i > 4; i--) swap(t[i], t[i - 1]);
        
        //操作C
        swap(t[1], t[6]), swap(t[6], t[2]), swap(t[6], t[5]);
        if(!h.count(t)) {
            q.push(t), h[t] = last + 1, res += 'C';
            kept[t] = kept[ls] + 'C';
        }
        //变回t
        swap(t[6], t[5]), swap(t[6], t[2]), swap(t[6], t[1]);
    }
    return -1;
}

int main() {
    string ed = "";
    for(int i = 0; i < 8; i++) {
        int x;
        cin >> x;
        ed += x + '0';
    }    
    int t = bfs(ed);
    cout << t << endl;
    if(t)
        cout << res << endl;
    return 0;
}

 

标签:魔板,kept,string,状态,int,USACO3.2,swap,操作,Magic
From: https://www.cnblogs.com/xioa-chou/p/16858537.html

相关文章

  • 【题解】洛谷 P1134 [USACO3.2]阶乘问题
     1#include<iostream>2usingnamespacestd;34intmain(){5intn;6cin>>n;7intc=1,a=0,b=0;8for(inti=1;i......
  • Magic Matrix
    传送门自己low思路:发现\(i,j,k\)可以随意互换,那么随意互换后容易得到\(a_i,a_j,a_k\)中最大值和次大值(不严格)一定相等。那么枚举\(i\),可以发现若\(a_{ij}<a_{i......
  • Leetcode第481题:神奇字符串(Magical string)
    解题思路根据题意,我们可以把ss看成是由「11组」和「22组」交替组成的,重点在于每组内的数字是一个还是两个,这可以从ss自身上知道。构造到ss的长度达到nn时停止......
  • Ansible 魔法变量(magic variables)和Facts变量
    AnsibleFacts要这样玩才让人心服Ansible体系文章,IT民工金鱼哥希望能以通俗易懂、诙谐幽默的方式给大家呈现这些枯燥的知识点,让繁重的学习变的有趣一些。1.前言描述......
  • CF878D Magic Breeding
    不妨考虑一种特殊情况,权值为\(0/1\)如何求解?此时\(k\)个数可以表示为\(n\)位二进制数,注意到位是独立的,将每一位拆开后最多只会有\(\min(2^k,n)\)种不同的情况。......
  • tmagic-editor本地运行
    直接用官网或git上的教程不能直接本地运行起来,要按照以下步骤才可以:1、在github下载好代码2、按照github提示那样,分别npminstall-gpnpm、pnpmbootstrap,先不要pnpmpl......
  • 像搭积木一样做3D像素场景——Magicavoxel
    MagicaVoxel体积非常的小,只有几M的内存,解压后直接打开应用程序即可使用。工具使用简单直观,能够方便的构建体素模型。MagicaVoxel支持WIN和MAC。在推特上还能看到很多设......
  • imagemagick: 多图创建gif动图(ImageMagick 6.9.10-86)
    一,命令行例子:1,生成gif[lhdop@bloggif1]$convert-delay200a1.webpa2.webpa3.webpa4.webp-loop0a.gif-delay数字单位是10毫秒,图片切换的时间是该数字乘......
  • centos8(linux):通过源码编译安装imagemagick7(ImageMagick 7.1.0-51)
    一,ImageMagick的相关文档:1,官网:https://imagemagick.org/2,下载页https://imagemagick.org/script/download.php#linux如图:说明:刘宏缔的架构森林是一个......
  • imagemagick: 对损坏的gif图做拆分(ImageMagick 6.9.10)
    一,对正常的gif图拆分:[lhdop@blogimg2]$identifymaoshu.gifmaoshu.gif[0]GIF400x224400x224+0+08-bitsRGB256c0.000u0:00.001maoshu.gif[1]GIF400x22440......