zoukankan      html  css  js  c++  java
  • Luogu P2730 魔板 Magic Squares

    P2730 魔板 Magic Squares

    题目背景

    在成功地发明了魔方之后,鲁比克先生发明了它的二维版本,称作魔板。这是一张有8个大小相同的格子的魔板:

    1 2 3 4

    8 7 6 5

    题目描述

    我们知道魔板的每一个方格都有一种颜色。这8种颜色用前8个正整数来表示。可以用颜色的序列来表示一种魔板状态,规定从魔板的左上角开始,沿顺时针方向依次取出整数,构成一个颜色序列。对于上图的魔板状态,我们用序列(1,2,3,4,5,6,7,8)来表示。这是基本状态。

    这里提供三种基本操作,分别用大写字母“A”,“B”,“C”来表示(可以通过这些操作改变魔板的状态):

    “A”:交换上下两行;

    “B”:将最右边的一列插入最左边;

    “C”:魔板中央四格作顺时针旋转。

    下面是对基本状态进行操作的示范:

    A: 8 7 6 5

    1 2 3 4

    B: 4 1 2 3

    5 8 7 6

    C: 1 7 2 4

    8 6 3 5

    对于每种可能的状态,这三种基本操作都可以使用。

    你要编程计算用最少的基本操作完成基本状态到目标状态的转换,输出基本操作序列。

    输入输出格式

    输入格式:

    只有一行,包括8个整数,用空格分开(这些整数在范围 1——8 之间)不换行,表示目标状态。

    输出格式:

    Line 1: 包括一个整数,表示最短操作序列的长度。

    Line 2: 在字典序中最早出现的操作序列,用字符串表示,除最后一行外,每行输出60个字符。

    输入输出样例

    输入样例#1:

    2 6 8 4 5 7 3 1 
    

    输出样例#1:

    7 
    BCABCCB
    

    说明

    题目翻译来自NOCOW。

    USACO Training Section 3.2

    题解:

    这是一道简单的宽搜题。

    因为这是期末考完写的第一道题,所以手感很差,写了好久。

    把序列哈希出一个值后就可以用数组(几步可以实现,这一步实现的方法,上一步是哪一个)存了。

    还有输出的时候用直接用栈来帮助比较快。

    其实这题数据很弱,直接用map也是可以的。

    因为太容易了,所以就不详细讲了。

    #include<bits/stdc++.h>
    namespace ZDY{
        #define ll long long
        #define db double
        #define sht short
        #define MB template <class T>
        #define Fur(i,x,y) for(int i=x;i<=y;i++)
        #define fur(i,x,y) for(int i=x;i<=y;i++)
        #define Fdr(i,x,y) for(int i=x;i>=y;i--)
        #define clr(x,y) memset(x,y,sizeof(x))
        #define cpy(x,y) memcpy(x,y,sizeof(x))
        #define fl(i,x) for(ri i=head[x],to;to=e[i].to,i;i=e[i].nxt)
        #define inf 0x3f3f3f3f
        #define fin(s) freopen(s".in","r",stdin)
        #define fout(s) freopen(s".out","w",stdout)
        #define l2(n) (ceil(log2(n)))
        MB T ABS(T x){return x>0?x:-x;}
        MB T MAX(T x,T y){return x>y?x:y;}
        MB T MIN(T x,T y){return x<y?x:y;}
        MB T GCD(T x,T y){return y?GCD(y,x%y):x;}
        void SWAP(int &x,int &y){x^=y;y^=x;x^=y;}
        //char gc(){static char buf[1000000],*s,*t;return s==t?(((t=(s=buf)+fread(buf,1,1000000,stdin))==s)?-1:*s++) : *s++;}
        #define gc getchar
        int gi(){int x=0,f=0;char c=gc();while(c<'0'||'9'<c){if(c=='-')f=!f;c=gc();}while('0'<=c&&c<='9'){x=x*10+c-48;c=gc();}return f?(-x):x;}
    }using namespace ZDY;using namespace std;
    #define N 30000007
    struct mf{
        int a[2][4];
        void b(int p){
            if(p==1)Fur(i,0,3)SWAP(a[0][i],a[1][i]);
            if(p==2)Fdr(i,3,1)SWAP(a[0][i],a[0][(i+4-1)%4]),SWAP(a[1][i],a[1][(i+4-1)%4]);
            if(p==3){int t=a[1][1];a[1][1]=a[1][2];a[1][2]=a[0][2];a[0][2]=a[0][1];a[0][1]=t;}
        }
        void get(){Fur(i,0,3)a[0][i]=gi();Fdr(i,3,0)a[1][i]=gi();}
        int hash(){int t=0;Fur(i,0,3)t=t*10+a[0][i];Fdr(i,3,0)t=t*10+a[1][i];return t%N;}
    }q[N];
    int v[N],la[N],k[N],ans;
    void dfs(mf x){
        if(la[x.hash()])dfs(q[la[x.hash()]]);
        putchar(k[x.hash()]+'A'-1);
    }
    void bfs(){
        int h=0,t=1;
        mf x,n;
        while(h<t){
            x=q[h++];
            if(x.hash()==ans){
                printf("%d
    ",v[ans]-1);
                dfs(x);
                return;
            }
            Fur(i,1,3){
                n=x;n.b(i);
                if(!v[n.hash()]){v[n.hash()]=v[x.hash()]+1;la[n.hash()]=h-1;k[n.hash()]=i;q[t++]=n;}
            }
        }
    }
    int main(){
        mf x;x.get();
        ans=x.hash();
        if(ans==12345678){printf("0
    ");exit(0);}
        Fur(i,0,3)q[0].a[0][i]=i+1;
        Fur(i,0,3)q[0].a[1][i]=8-i;
        v[q[0].hash()]=1;
        bfs();
    }
    
  • 相关阅读:
    转!!javaMail使用网易163邮箱报535 Error: authentication failed
    银行卡验证(验证是否存在,卡号类型,归属行)
    Navicat已经成功连接,密码忘记的解决方法
    Inline&IAT Hook原理
    x64dbg尝鲜
    C# 通过Dynamic访问System.Text.Json对象
    dotnet5将asp.net webapi宿主到wpf
    Asp.Net5 MVC with Vue.js
    在 Visual Studio 中使用跟踪点将信息记录到“输出”窗口中
    WPF带阴影的无边框窗体
  • 原文地址:https://www.cnblogs.com/mimiorz/p/10279707.html
Copyright © 2011-2022 走看看