hiho 1654

(简单搜索)
题意:4x4的棋盘上有X和Y两种棋子各若干枚,求最少移动多少次棋子可以达到胜利局面:有4个X或者4个Y连成一行、一列或者对角线(两条对角线都算胜利)。

思路:直接bfs搜索写起来~(在移动棋子位置后忘了移动回来到原来的状态,这个bug检查了我一个小时…还是太久没写代码了,这是个教训OTZ)

#include <cstdio>
#include <queue>
#include <cstring>
#include <algorithm>
#define LL long long
#define ull unsigned long long

using namespace std;
const int maxn = 50000000;

char mp[5][5];
int num_mp[5][5];
bool vis[maxn];
struct node{
    int cur, step;
    node(int a=0, int b=0):cur(a),step(b){}
};
queue<node> Q;

bool judge(int x) {
    for(int i=0; i<4; i++) {
        if(num_mp[i][0]==x && num_mp[i][1]==x && num_mp[i][2]==x && num_mp[i][3]==x) return 1;
        if(num_mp[0][i]==x && num_mp[1][i]==x && num_mp[2][i]==x && num_mp[3][i]==x) return 1;
    }
    if(num_mp[0][0]==x && num_mp[1][1]==x && num_mp[2][2]==x && num_mp[3][3]==x) return 1;
    if(num_mp[0][3]==x && num_mp[1][2]==x && num_mp[2][1]==x && num_mp[3][0]==x) return 1;
    return 0;
}

int num_hash() {
    int ret = 0;
    for(int i=0; i<4; i++)
        for(int j=0; j<4; j++) {
            ret = 3*ret + num_mp[i][j];
        }
    return ret;
}

void get_num_mp(int t) {
    for(int i=3; i>=0; i--) {
        for(int j=3; j>=0; j--) {
            num_mp[i][j] = t % 3;
            t /= 3;
        }
    }
}

int dx[4] = {1, -1, 0, 0};
int dy[4] = {0, 0, 1, -1};
bool valid(int x) {
    if(0 <= x && x < 4) return 1;
    return 0;
}

int main() {
    //freopen("in.txt","r",stdin);
    while(scanf("%s",mp[0]) == 1) {
        for(int i=1; i<4; i++)
            scanf("%s",mp[i]);
        int head = 0, ans = -1;
        for(int i=0; i<4; i++)
            for(int j=0; j<4; j++){
                int t = 0;
                if(mp[i][j] == 'X') t = 1;
                if(mp[i][j] == 'Y') t = 2;
                head = 3*head + t;
            }
        memset(vis, 0, sizeof(vis));
        while(!Q.empty()) Q.pop();
        Q.push(node(head, 0)); vis[head] = 1;
        while(!Q.empty()) {
            node nd = Q.front(); Q.pop();
            get_num_mp(nd.cur);
            //printf("------step: %d\n",nd.step);
            if(judge(1) || judge(2)) {
                ans = nd.step;
                break ;
            }
            for(int i=0; i<4; i++)
                for(int j=0; j<4; j++) if(num_mp[i][j] == 0) {
                    for(int k=0; k<4; k++) {
                        int nowx = i + dx[k], nowy = j + dy[k];
                        if(valid(nowx) && valid(nowy) && num_mp[nowx][nowy]) {
                            swap(num_mp[i][j], num_mp[nowx][nowy]);
                            int hs = num_hash();
                            swap(num_mp[i][j], num_mp[nowx][nowy]);
                            if(vis[hs]) continue ;
                            vis[hs] = 1;
                            Q.push(node(hs, nd.step+1));
                        }
                    }
                }
        }
        printf("%d\n",ans);
    }
    return 0;
}
发布了40 篇原创文章 · 获赞 44 · 访问量 9万+

猜你喜欢

转载自blog.csdn.net/Site1997/article/details/78786829