柯南再破难关

柯南再破难关

题目描述:

OIBH组织派出的黄金十二人+青铜五小强还没有到, 他们只能指望原先的机关能够阻拦住柯南的脚步,柯南打开大门之后发现里面还有一个门, 门上还有一个神奇的锁(-,-),这是一个4*4的锁, 上面有8个凸起的格子和8个被按下的格子,当且仅当两个格子有公共边时, 则称这两个格子是相邻的。

1518789084817787.png

每次操作只能够交换相邻的两个格,柯南看到了初始锁的状态和目标锁的状态,同样组织只允许他用最少步数打开锁。

输入格式:

第1到4行每行四个数字(1或者0),描述了初始锁状态
接着是一个空行

第6到9行每行四个数字,描述了最终锁状态

输出格式:

输出文件只有一行,是一个整数n,表示最少的操作次数。

样例输入:

1111
0000
1110
0010

1010
0101
1010
0101

样例输出:

4

提示:

本题是非常典型的广搜题,难点在于hash表的设计。

时间限制:1000ms
空间限制:128MByte

#include<bits/stdc++.h>
using namespace std;
struct node{
    int a[5][5];
    bool operator == (const node &b) const
    {
        for(int i = 1; i <= 4; i++)
            for(int j = 1; j <= 4; j++)
                if(a[i][j] != b.a[i][j]) return 0;
        return 1;
    }
};
struct enode{
    node a;
    int step;
    enode(node a1, int s1) : a(a1), step(s1) {}
};
queue<enode> q;
int b[4][2] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
bool p[65536];

bool pd(node x)
{
    int sum = 0;
    for(int i = 1; i <= 4; i++)
        for(int j = 1; j <= 4; j++) sum += x.a[i][j] * pow(2, (i - 1) * 4 + (j - 1));
    return p[sum];
}

void se(node x)
{
    int sum = 0;
    for(int i = 1; i <= 4; i++)
        for(int j = 1; j <= 4; j++) sum += x.a[i][j] * pow(2, (i - 1) * 4 + (j - 1));
    p[sum] = 1;
}

int main()
{
    char ch;
    node st, fin;
    for(int i = 1; i <= 4; i++)
        for(int j = 1; j <= 4; j++) cin>>ch, st.a[i][j] = ch - '0';
    for(int i = 1; i <= 4; i++)
        for(int j = 1; j <= 4; j++) cin>>ch, fin.a[i][j] = ch - '0';
    q.push(enode(st, 0));
    se(st);
    while(!q.empty()){
        int x1, y1;
        node n = q.front().a;
        int st = q.front().step;
        q.pop();
        if(n == fin){
            cout<<st<<endl;
            return 0;
        }
        for(int i = 1; i <= 4; i++)
            for(int j = 1; j <= 4; j++)
                for(int k = 0; k < 4; k++){
                    x1 = i + b[k][0], y1 = j + b[k][1];
                    if(x1 > 0 && x1 <= 4 && y1 > 0 && y1 <= 4){
                        swap(n.a[i][j], n.a[x1][y1]);
                        if(!pd(n)){
                            se(n);
                            q.push(enode(n, st +1));
                        }
                        swap(n.a[i][j], n.a[x1][y1]);
                    }
                }
    }
    return 0;
}

 

 

posted @ 2018-07-20 13:19  wbss  阅读(253)  评论(0编辑  收藏  举报