码迷,mamicode.com
首页 > 其他好文 > 详细

棋盘游戏

时间:2019-09-30 22:00:33      阅读:109      评论:0      收藏:0      [点我收藏+]

标签:break   取出   color   ati   序列   ref   拓展   ret   bre   

https://loj.ac/problem/10029

题目描述

  在一个4×4的棋盘上有 8个黑棋和8个白棋,当且仅当两个格子有公共边,这两个格子上的棋是相邻的。移动棋子的规则是交换相邻两个棋子。
给出一个初始棋盘和一个最终棋盘,请找出一个最短的移动序列使初始棋盘变为最终棋盘,输出最短序列的长度。

思路

  数据如此之小,显然是要我们搜索。而这里对棋盘可以直接简单的压缩为一个16位的二进制数,那么显然我们可以很好的存储状态。接下来要考虑的就是如何对当前状态进行拓展。首先我们易知操作世界上只有两种,一是交换左右棋子,二是交换上下棋子,我们只需要用位运算取出每一位的颜色并且判断与之交换的棋子颜色是否相同,再尝试进行两种交换判是否出现过即可。

代码

#include <bits/stdc++.h>
using namespace std;
bool vis[70000];
int step[70000];
queue<int> q;
int main() 
{
    int a=0,b=0;
    char s[5];
    for(int i=1;i<=4;i++)
    {
        scanf(" %s",s);
        for(int j=0;j<4;j++)
            a=a*2+s[j]-0;
    }
    for(int i=1;i<=4;i++)
    {
        scanf(" %s",s);
        for(int j=0;j<4;j++)
            b=b*2+s[j]-0;
    }
    q.push(a);
    vis[a]=1;step[a]=0;
    int p;
    while(!q.empty())
    {
        int now=q.front();q.pop();
        if(now==b)
        {
            printf("%d",step[now]);
            break ;
        }
        for(int i=0;i<16;i++)
        {
            if(i%4!=0&&(now&(1<<i)^(now&(1<<i-1)))&&!vis[p=now^(1<<i)^(1<<i-1)])
            {
                vis[p]=1;
                step[p]=step[now]+1;
                q.push(p);
            }
            if(i<12&&(now&(1<<i))^(now&(1<<i+4))&&!vis[p=now^(1<<i)^(1<<i+4)])
            {
                vis[p]=1;
                step[p]=step[now]+1;
                q.push(p);
            }
        }
    }
    return 0;
}

 

棋盘游戏

标签:break   取出   color   ati   序列   ref   拓展   ret   bre   

原文地址:https://www.cnblogs.com/fangbozhen/p/11614142.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!