BFS —— 信息学一本通(1451:棋盘游戏)
题目描述###
在一个4*4的棋盘上有8个黑棋和8个白棋,当且仅当两个格子有公共边,这两个格子上的棋是相邻的。移动棋子的规则是交换相邻两个棋子。现在给出一个初始棋盘和一个最终棋盘,要求你找出一个最短的移动序列使初始棋盘变为最终棋盘。
Klux说:“这么简单的题目,我都会做!”
输入格式:###
第1到4行每行四个数字(1或者0),描述了初始棋盘
接着是一个空行
第6到9行每行四个数字,描述了最终棋盘
输出格式:###
输出只有一行是一个整数n,表示最少的移动步数。
输入样例#1:
1111
0000
1110
0010
1010
0101
1010
0101
输出样例#1:
4
解题思路###
BFS+位运算。
由于要求最小步数可以看出BFS的基本框架,但是如果用矩阵存储状态的话太耗费空间而且很慢,注意到每个格子的状态非0即1而且总格子数目为16所以可以用二进制的方法存储状态,相应判断,转移,判重。
注意这里面将棋盘转换成二进制序列的时候,如何计算序列上的值在原4*4棋盘上的位置,以及使用异或运算去生成相邻格子交换后的新棋盘状态对应的二进制序列也是本题特色。
最后,由于是交换相邻的格子,理论上格子和上下左右四个方向都可以互换,但是显然对于每个格子这样枚举互换存在大量的重复,本质上对于每个格子从上至下、从左到右只需要让他往右和往下和相邻的格子尝试互换即可。
#include<iostream>
#include<queue>
#define FOR(a,b,c) for(int a=(b);a<(c);a++)
using namespace std;
const int maxn = 16;
struct Node{   // 结构体存棋盘的二进制序列和步数
    int num,d;
};
int A,B;
int vis[100000];
void BFS() {
queue<Node> q;
    q.push((Node){A,0});
    while(!q.empty())
    {
        Node u=q.front(); q.pop();
        int tmp=u.num;
        if(tmp==B) { cout<<u.d; return ; }
        for(int i=15;i>=0;i--)   // 棋盘对应的二进制序列,从高到低依次枚举每个位置
        {
            int x=(15-i)/4,y=(15-i)%4,w=1<<i,z;  //计算该位置在棋盘上的x和y坐标值
            if(y<3 && (tmp&(1<<i))!=(tmp&(1<<i-1)))   //向右交换,二进制序列的i和i-1交换
            {
                z=1<<i-1;
                if(!vis[tmp^z^w]) {
                    vis[tmp^z^w]=1;
                    q.push((Node){tmp^z^w,u.d+1});
                }
            }
            if(x<3 && (tmp&(1<<i))!=(tmp&(1<<i-4)))  //向下交换,二进制序列的i和i-4交换
            {
                z=1<<i-4;
                if(!vis[tmp^z^w]) {
                    vis[tmp^z^w]=1;
                    q.push((Node){tmp^z^w,u.d+1});
                }
            }
        }
    }
}
int main()
{
    char c;
    for(int i=15;i>=0;i--) {
        cin>>c;
        if(c!='0')  A += 1<<i;
    }
    for(int i=15;i>=0;i--) {
        cin>>c;
        if(c!='0')  B += 1<<i;
    }
    if(A==B) cout<<0;
    else BFS();
}
BFS —— 信息学一本通(1451:棋盘游戏)的更多相关文章
- 关于Hamilton问题的研究
		关于Hamilton问题的研究 首先介绍一下Hamilton问题:哈密顿问题寻找一条从给定的起点到给定的终点沿途恰好经过所有其他结点一次的路径.(摘自百度百科) 从刚开始学OI买了信息学一本通,这个问 ... 
- 题解 P2272 【[ZJOI2007]最大半连通子图】
		P2272 [ZJOI2007]最大半连通子图 萌新初学Tarjan,在<信息学奥赛一本通-提高篇>中看到这题,看到题解不多,便想发布一篇较为清新简洁的题解.--第5道紫题 题目大意: 定 ... 
- Pop Sequence  题解
		Pop Sequence(PAT) https://www.nowcoder.com/pat/5/problem/4090 前言: PAT上一道Stack的应用题,简化版的有<信息学一本通·普及 ... 
- $ybt\ 【信息学奥赛一本通】题解目录$
		[信息学奥赛一本通]题解目录 $ \large -> OJ$ $ problem1000 $ \(Answer\) - > $ \large 1000$ $ problem1001 $ \ ... 
- 信息学竞赛一本通提高版AC题解—例题1.1活动安排
		书中代码有误.书中为sort(a+1,a+n+1,Cmp). // // Created by yuxi on 19-1-13. // /* * * <信息学竞赛一本通-提高版>全部AC解 ... 
- 【信息学奥赛一本通】第三部分_队列 ex2_3produce 产生数
		给出一个整数n(n<=2000)(代码可适用n<=10^31)和k个变换规则(k<=15). 规则:1.1个数字可以变换成另1个数字: 2.规则中右边的数字不能为零. BFS #in ... 
- 2019寒假练题计划——LibreOJ刷题计划 &《信息学奥赛一本通》提高版题目
		目录 2019.1.27 #10082. 「一本通 3.3 例 1」Word Rings 题意 思路 #10083. 「一本通 3.3 例 2」双调路径 题意 思路 #10084. 「一本通 3.3 ... 
- 九度OJ 1091:棋盘游戏 (DP、BFS、DFS、剪枝)
		时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:1497 解决:406 题目描述: 有一个6*6的棋盘,每个棋盘上都有一个数值,现在又一个起始位置和终止位置,请找出一个从起始位置到终止位置代 ... 
- Keyboarding(信息学奥赛一本通-T1452)
		[题目描述] 出自 World Final 2015 F. Keyboarding 给定一个 r 行 c 列的在电视上的"虚拟键盘",通过「上,下,左,右,选择」共 5 个控制键, ... 
随机推荐
- (五)聊一聊深Copy与浅Copy
			一.关于浅copy与深copy 首先说明一下: 在python中,赋值其实就是对象的引用,变量就是对象的一个标签,如果把内存对象比喻成一个个房间,那么变量就是门牌号. 深copy与浅copy只是针对可 ... 
- JS数组(JSON)整合篇-方法整理
			遍历:arr_Param.forEach(function (item, i) {}); 反序排序:arr_Param.reverse(); 合并数组:arr_Param.push.apply(arr ... 
- 小程序通过 url 向内嵌 H5 传参注意事项
			当在小程序中通过 url 向 <web-view> 内嵌的 H5 传参时,当包含特殊字符时需要进行编码处理(不然 <web-view> 中是拿不到值的,小程序竟然没有错误提示. ... 
- vue  keep-alive内置缓存组件
			1.当组件在keep-alive被切换时将会执行activeted和deactiveted两个生命周期 2.inlude 正则表达式或字符串 ,只有符合条件的组件会被缓存 exclude正则表达式或字 ... 
- # 20175333曹雅坤《Java程序设计》第七周学习总结
			教材学习内容总结 第八章-常用实用类String类 构造String对象 字符串的并置 String类的常用方法 字符串与基本数据的互相转化 对象的字符串表示 字符串与字符.字节数组 正则表达式及字符 ... 
- java学习笔记06-条件语句
			java条件语句 if...else 单独使用if if(布尔表达式){ 如果布尔表达式为true,执行花括号里的代码 } public static void main(String[] args) ... 
- form表单中button按钮返回上一页解决办法
			解决Form中button按钮不好用的问题解决办法. 方法一: 1.在Form表单标签中国增加一个属性,如下图,红框处 2.返回按钮样式 3.onclick方法需要跳转的页面,遮挡处为需要返回的页面 ... 
- python学习之re  (?P...)通过关键字获取组以及( P=name)
			和其他的RE表达式一样,但是匹配的子串可以通过group的名字 name来获取.即 result.group('name') (提示,字符串数字都是常量,所以关键字都可以被视为整型(hash结果) ... 
- 关于CSRF
			CSRF介绍 CSRF(Cross-site request forgery)跨站请求伪造,也被称为“One Click Attack”或者Session Riding,通常缩写为CSRF或者XSRF ... 
- 初识中间件Kafka
			初识中间件Kafka Author:SimplelWu 什么是消息中间件? 非底层操作系统软件,非业务应用软件,不是直接给最终用户使用的,不能直接给客户带来价值的软件统称为中间件 关注于数据的发送和接 ... 
