首页 > 其他 > 详细

Problem D: 【宽搜入门】魔板

时间:2020-04-10 17:24:42      阅读:98      评论:0      收藏:0      [点我收藏+]

Description

在成功地发明了魔方之后,鲁比克先生发明了它的二维版本,称作魔板。这是一张有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个字符。

 

 

Sample Input

 

2 6 8 4 5 7 3 1

Sample Output

7

BCABCCB 

 

最终AC代码:

#include <bits/stdc++.h>
using namespace std;
//本题的难点在于 需要记录之前出现的状态 本题采用string来表示
//题干没有说明未找到的情况,还有输入的序列就是初始序列的情况(经测试,都是BFS()都是返回""
//题干虽然说每行只输出60个字符,然而没有情况超过60个字符的。。。 
struct Node{ 
    int M[2][4]; //M保存状态 
    string s; //累计操作 
}now, nex;
int des[2][4];
char op[3] = {A, B, C};
map<string, bool> mp;
void getMatrix(char c){
    int i;
    if(c == A){
        for(i=0; i<4; i++) nex.M[0][i] = now.M[1][i];
        for(i=0; i<4; i++) nex.M[1][i] = now.M[0][i];
    }else if(c == B){
        for(i=0; i<2; i++) nex.M[i][0] = now.M[i][3];
        for(i=1; i<4; i++) nex.M[0][i] = now.M[0][i-1];
        for(i=1; i<4; i++) nex.M[1][i] = now.M[1][i-1];
    }else{
        for(i=0; i<2; i++) nex.M[i][0]=now.M[i][0], nex.M[i][3]=now.M[i][3];
        nex.M[0][1]=now.M[1][1], nex.M[0][2]=now.M[0][1];
        nex.M[1][1]=now.M[1][2], nex.M[1][2]=now.M[0][2];
    }
}
bool Judge(Node node){
    int i, j;
    for(i=0; i<2; i++){
        for(j=0; j<4; j++) if(node.M[i][j] != des[i][j]) return false;
    }
    return true;
}
string getStr(Node node){
    int i;
    string str;
    for(i=0; i<4; i++) str += (node.M[0][i] + 0);
    for(i=0; i<4; i++) str += (node.M[1][i] + 0);
    return str;
}
string BFS(){
    string str;
    int i, len;
    now.s = "";
    for(i=0; i<4; i++) now.M[0][i] = i+1;
    now.M[1][0]=8, now.M[1][1]=7, now.M[1][2]=6, now.M[1][3]=5;
    queue<Node> q;
    if(Judge(now)) return now.s;
    q.push(now);
    mp[getStr(now)] = true;
    while(!q.empty()){
        now = q.front();
        q.pop();
        for(i=0; i<3; i++){
            nex.s = now.s + op[i];
            getMatrix(op[i]);
            if(Judge(nex)) return nex.s;
            str = getStr(nex);
            if(!mp[str]){
                q.push(nex);
                mp[str] = true;
            }
        }
    }
    return "";
}
int main(){
    int i;
    string ans;
    while(cin>>des[0][0]>>des[0][1]>>des[0][2]>>des[0][3]){ //输入第一组 
        cin>>des[1][3]>>des[1][2]>>des[1][1]>>des[1][0]; //输入第二组 
        mp.clear();
        ans = BFS();
        printf("%d\n", ans.size());
        for(i=0; i<ans.size(); i++) printf("%c", ans[i]);
        printf("\n");
    }
    return 0;
}

总结:这题和上一题其实大同小异,唯一不同的是,这里需要记录出现的状态,否则某些情况会出现死循环从而造成超时。但是,我想吐槽,这题干的描述真的不怎样,尤其是输出!

Problem D: 【宽搜入门】魔板

原文:https://www.cnblogs.com/heyour/p/12674467.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!