【2018寒假集训 Day1】【位运算】翻转游戏
翻转游戏(flip)
【问题描述】
翻转游戏是在一个 4 格×4 格的长方形上进行的,在长方形的 16 个格上每
个格子都放着一个双面的物件。每个物件的两个面,一面是白色,另一面是黑色,
每个物件要么白色朝上,要么黑色朝上,每一轮你只能翻 3 至 5 个物件,从而由
黑到白的改变这些物件上面的颜色,反之亦然。每一轮被选择翻转的物件遵循以
下规则:
1、从 16 个物件中任选一个。
2、翻转所选择的物件的同时,所有与它相邻的左方物件、右方物件、上方物件
和下方物件(如果有的话),都要跟着翻转。
以下为例:
bwbw
wwww
bbwb
bwwb
这里”b”表示该格子放的物件黑色面朝上、”w”表示该格子放的物件白色朝
上。如果我们选择翻转第三行的第一个物件(如图所示),那么格子状态将变为:
bwbw
bwww
wwwb
wwwb
游戏的目标是翻转到所有的物件白色朝上或黑色朝上。你的任务就是写一个
程序来求最少的翻转次数来实现这一目标。
【输入格式】flip.in
输入文件包含 4 行,每行 4 个字符,每个字符”w” 或 “b”表示游戏开始时格子
上物件的状态。
【输出格式】flip.out
输出文件仅一个整数,即从给定状态到实现这一任务的最少翻转次数。如果给定
的状态就已经实现了目标就输出 0,如果不可能实现目标就输出”Impossible”。
【输入样例】
bwwb
bbwb
bwwb
bwww
【输出样例】
4
【解题思路】
把黑白当作01,把图每一行相接形成一行,转换成01串后化成十进制。
用BFS对每一个点进行翻转,从一个图可以拓展出16种状态,接着继续拓展。
而对每一个点的翻转操作,可以利用位运算中的异或运算。
依照参考程序中的做法,对左上角的翻转操作就是异或19,对右下角的翻转操作就是异或51200。
计算方法就是把要翻转的位置当作是1,别的位置当作是0,按照开头的方法转化成01串后转化成10进制。
【参考程序】
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int num;
string st,sr;
bool visit[65536];
struct data
{
int pic,step;
}que[65536];
int trans(string st)//b当作是1,w当作是0,转换成十进制整数
{
int ans=0,tmp=1;
if (st[0]=='b') ans+=tmp;
for (int i=1;i<=15;i++)
{
tmp=tmp<<1;
if (st[i]=='b')ans+=tmp;
}
return ans;
}
const int table[16]={19,39,78,140,305,626,1252,2248,4880,10016,20032,35968,12544,29184,58368,51200};//打表
int bfs(int num)
{
if (num==0||num==65535)
{
cout<<0;
return 0;
}
int head=0,tail=1;
que[head].pic=num;que[head].step=0;
visit[num]=true;
while (head<tail)
{
for (int i=0;i<16;i++)//拓展
{
que[tail].pic=que[head].pic^table[i];//翻转操作
if (!visit[que[tail].pic])
{
que[tail].step=que[head].step+1;
visit[que[tail].pic]=true;
if (que[tail].pic==0||que[tail].pic==65535)//判断是否到达目标
{
cout<<que[tail].step<<endl;
return 0;
}
tail++;
}
}
head++;
}
return -1;
}
int main()
{
freopen("flip.in","r",stdin);
freopen("flip.out","w",stdout);
cin>>st;
cin>>sr;st=st+sr;
cin>>sr;st=st+sr;
cin>>sr;st=st+sr;//转化成一行
int num=trans(st);
int ans=bfs(num);
if (ans==-1) cout<<"Impossible";
return 0;
}
【2018寒假集训 Day1】【位运算】翻转游戏的更多相关文章
- 【2018寒假集训 Day1】【位运算】桐桐的运输方案
桐桐的运输方案(transp) [问题描述] 桐桐有 N 件货物需要运送到目的地,它们的重量和价值分别记为: 重量:W1,W2,…,Wn: 价值:V1,V2,…,Vn: 已知某辆货车的最大载货量为 X ...
- 牛客2018国庆集训 DAY1 D Love Live!(01字典树+启发式合并)
牛客2018国庆集训 DAY1 D Love Live!(01字典树+启发式合并) 题意:给你一颗树,要求找出简单路径上最大权值为1~n每个边权对应的最大异或和 题解: 根据异或的性质我们可以得到 \ ...
- 【2018寒假集训Day 1】【位运算】生成字符串
生成字符串(strs) [问题描述] 假设字符串只由字符“0”,“1”,“”组成,其中字符“”表示该字符可由 字符“0”或“1”替代. 现有一些字符串,根据这些字符串生成所有可生成的字符串.如: {1 ...
- 【2018寒假集训 Day2】【2019.5.11更新】【动态规划】花店橱窗布置(FLOWER)
花店橱窗布置(FLOWER) 提交文件名:flower 问题描述: 某花店现有F束花,每一束花的品种都不一样,同时至少有同样数量的花瓶,被按顺序摆成一行,花瓶的位置是固定的,从左到右按1到V顺序编号, ...
- 【2018寒假集训 Day2】【动态规划】维修栅栏
维修栅栏 问题描述: 小z最近当上了农场主!不过,还没有来得及庆祝,一件棘手的问题就摆在了小z的面前.农场的栅栏,由于年久失修,出现了多处破损.栅栏是由n块木板组成的,每块木板可能已经损坏也可能没有损 ...
- 【2018寒假集训 Day2】【动态规划】钱币兑换(exchange)(自己翻译的2333)
钱币兑换(exchange) 问题描述: Dave偶然获得了未来几天的美元(dollars)与马克(marks)之间的兑换率.例如Dave开始有100marks,请编写个程序帮助Dave找出最好的买卖 ...
- 【集训Day4 动态规划】【2018寒假集训 Day4 更新】蛙人
蛙人 (ple) 蛙人使用特殊设备潜水.设备中有一个气瓶,分两格:一格装氧气,另一格装氮气.留在水中有时间的限制,在深水中需要大量的氧气与氮气.为完成任务,蛙人必须安排好气瓶.每个气瓶可以用它的重量和 ...
- 清北学堂寒假集训DAY1
第一天,上午讲了些基本的技巧和简单算法,主要就是适应这里. 中午跑到食堂吃了顿“饭”(我并没有挖苦233333),然后回宿舍休息休息 因为 迎接我们的是模拟啊啊啊啊啊阿 下午题一发下来,并没有想象中的 ...
- 洛谷2018寒假集训tg第二次比赛第二题Princess Principal题解
这算不算泄题啊...被kkk发现会咕咕咕吧. 题目大意:给定一个数列a,与常数n,m,k然后有m个询问,每个询问给定l,r.问在a[l]到a[r]中最少分成几段,使每段的和不超过k,如果无解,输出Ch ...
随机推荐
- jQuery的原生替代
jQuery的原生替代,参考自你不需要jQuery,对其进行了更清晰的总结与分类,现代游览器基本都支持(ie10+以上),只整理了最简洁实用的原生代码,过分累赘的实现没有加入 元素获取 jQuery ...
- 页面离开前提示用户(onbeforeunload 事件)
window.onbeforeunload = function (e) { var evt = e || window.event; evt.returnValue = '离开会使编写的内容丢失'; ...
- js控制进度条数据
<style><!-- #time{ width:500px; height: 20px; background: red; border-radius: 10px; } --> ...
- 媒体查询文字大小.html
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- 选择器, ,>,+,~
一.后代选择器 选取指定元素的后代元素 与子元素选择器相比,后代选择器选取的不一定是直接后代(儿子),而是作用于所有后代元素(儿子.孙子.重孙…)都可以. 二.(>)子元素选择器 选取某个元素的 ...
- FastJson的使用心得
本文为早前整理,参考文献已找不到,如有侵权请与我联系,添加参考链接. 一丶基本使用 1.1主要API fastjson入口类是com.alibaba.fastjson.JSON,主要的API是JS ...
- 设计模式C++描述----14.外观(Facade)模式
一. 举例说明 还以我以前做的文件系统(FileSys)为例: 文件系统是一个独立的系统,它提供一套核心的文件操作. 除了文件系统,还有四个子系统,分别是杀毒子系统(KillVirus),压缩子系统( ...
- podman初试-和docker对比
podman初试-和docker对比 1,什么是docker? Docker 是一个开源的应用容器引擎,属于 Linux 容器的一种封装,Docker 提供简单易用的容器使用接口,让开发者可以打包他们 ...
- 通过Value获取Map中的键值Key的四种方法
1 简介 我们都知道Map是存放键值对<Key,Value>的容器,知道了Key值,使用方法Map.get(key)能快速获取Value值.然而,有的时候我们需要反过来获取,知道Value ...
- PyCharm的几个使用技巧
PyCharm是个十分强大的Python编辑器,笔者在日常的工作中学到了很多该IDE的使用技巧,有的是从别人那里学到的,有的是自己学习的.笔者深感自己的开发能力不足,因此希望能够将这些使用技巧记录 ...