您的位置:首页 > 其它

【2018寒假集训 Day1】【位运算】翻转游戏

2018-02-01 21:38 225 查看
翻转游戏(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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: