poj1753 Flip Game
题意:4*4的正方形,每个格子有黑白两面,翻转格子使得4*4个格子显示全黑或全白,翻转要求:选中的那个格子,以及其上下左右相邻的格子(如果存在)要同时翻转。输出最小的达到要求的翻转次数或者Impossible(如果不可能)
题目链接:http://poj.org/problem?id=1753
分析:因为每个格子只有黑白两面,所以对于每个格子来说,要么不翻转,要么翻转一次,因为翻转奇数次结果和翻转一次得到的效果是一样的,而翻转偶数次得到的效果和不翻转是一样的,则总共有16个格子,最多要翻转16次,每个格子有黑白两种颜色,假设每一次面临的4*4正方形代表一个状态,则总共有2^16种状态,可以用16位二进制数表示,每一位1代表'b'(白),0代表'w'(黑)。当状态为(0或者65535)时则达到要求。
注意:1.因为只用求最少次数,用bfs做,将每一个没有访问到的状态 (用vis[]数组标记) 加入到队列中,如果游戏无法完成,状态必定会形成循环,由于重复状态不会再次入队,所以最后的队列一定会是空队列。当队列为空时说明此时还未达到要求,则是Impossible
2.二进制运算,翻转某一个格子即指将1变成0,0变成1.这里可以用异或运算的性质,1^0=1,0^0=0;所以只用将需要翻转的那个格子对应的16位二进制数的位置为1,其他不翻转的格子对应的16位二进制数的位置为0得到一个数和当前状态的16位二进制数异或即可得到翻转后的状态。
例如:
bwwb
bbwb
bwwb
bwww
的状态可以表示为1001 1101 1001 1000 (二进制),如果我现在要翻转第一行第一个格子,则可以用此二进制数和1100 1000 0000 0000 异或,则可以得到下一个状态next=1001 1101 1001 1000 ^ 1100 1000 0000 0000 = 0101 0101 1001 1000
即:
wbwb
wbwb
bwwb
bwww
可以得到转换每一个格子需要异或的二进制数(十进制表示):
int change[16] = {
51200,58368,29184,12544,
35968,20032,10016,4880,
2248,1252,626,305,
140,78,39,19
};
代码:
int dir[][]={{,},{-,},{,},{,-}};
void init()
{
int i,j,x,y,t,temp;
for(i=;i<;++i)
{
for(j=;j<;++j)
{
temp = ;
temp ^= (<<( - ( i* + j )));
for(t=;t<;++t)
{
x = i + dir[t][];
y = j + dir[t][];
if(x< || y< || x> || y>)
continue;
temp ^= (<<((-x)*+-y));
}
cout<<temp<<" ";
}
cout<<endl;
}
}
完整代码1:(bfs+bit)
#include<iostream>
#include<cstdio>
#include<queue>
#include<cmath>
#include<string>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
char m[][];
//int di[4][2]={{1,0},{0,1},{-1,0},{0,-1}};
struct Node
{
int state,step;
}nod[];
int vis[];
/*
int change[16] = //16种状态转换,对应4*4的翻子位置 方法2.直接异或得到状态
{
51200,58368,29184,12544,
35968,20032,10016,4880,
2248,1252,626,305,
140,78,39,19
};
*/
int getChang(int stat,int x,int y) //方法1.翻转需要翻转的格子
{
int tp=stat;
tp^=(<<(-x*-y));
if(x>) tp^=(<<(-(x-)*-y)); //上
if(x<) tp^=(<<(-(x+)*-y)); //下
if(y>) tp^=(<<(-x*-y+)); //左
if(y<) tp^=(<<(-x*-y-)); //右
return tp;
}
int bfs(Node cur)
{
queue<Node>q;
q.push(cur);
Node next;
vis[cur.state]=; while(!q.empty())
{
cur=q.front();
q.pop();
if(cur.state==||cur.state==) //判断是否全黑/全白
return cur.step;
for(int i=;i<;i++)
{
for(int j=;j<;j++)
{
next.state=getChang(cur.state,i,j); //按部得到状态
//next.state=cur.state^change[i]; //直接异或得到状态 (循环要改为for(int i=0;i<16;i++) )
next.step=cur.step+;
if(next.state==||next.state==)
return next.step;
if(vis[next.state]) //是否已经入队过
continue;
q.push(next);
vis[next.state]=;
}
}
}
return -;
}
int main()
{
memset(vis,,sizeof(vis));
int tmp=;
for(int i=;i<;i++)
{
cin>>m[i];
for(int j=;j<;j++)
{
if(m[i][j]=='b')
tmp+=(<<(-*i-j));
}
}
Node cur;
cur.state=tmp;
cur.step=;
int ans=bfs(cur);
if(ans==-)
printf("Impossible\n");
else
printf("%d\n",ans);
return ;
}
完整代码2:(dfs)
#include<iostream>
#include<cstdio>
#include<cmath>
#include<queue>
#include<vector>
#include<map>
#include<algorithm>
#include<string>
#include<cstring>
using namespace std;
int mp[][];
int step;
bool flag;
int judge()
{
for(int i=;i<;i++)
for(int j=;j<;j++)
if(mp[i][j]!=mp[][])
return ;
return ;
}
void flip(int x,int y)
{
mp[x][y]=!mp[x][y];
if(x>) mp[x-][y]=!mp[x-][y];
if(x<) mp[x+][y]=!mp[x+][y];
if(y>) mp[x][y-]=!mp[x][y-];
if(y<) mp[x][y+]=!mp[x][y+];
}
void dfs(int x,int y,int deep)
{
if(deep==step)
{
flag=judge();
return;
}
if(flag||x>=)
return;
flip(x,y);
if(y<)
dfs(x,y+,deep+);
else
dfs(x+,,deep+);
flip(x,y);
if(y%<)
dfs(x,y+,deep);
else
dfs(x+,,deep);
return;
}
int main()
{
string s;
flag=;
for(int i=;i<;i++)
{
cin>>s;
for(int j=;j<;j++)
if(s[j]=='b')
mp[i][j]=;
}
for(step=;step<=;step++)
{
dfs(,,);
if(flag)
break;
}
if(flag)
printf("%d\n",step);
else
printf("Impossible\n");
return ;
}
poj1753 Flip Game的更多相关文章
- poj1753 Flip Game(BFS+位压缩)
题目链接 http://poj.org/problem?id=1753 题意 一个棋盘上有16个格子,按4×4排列,每个格子有两面,两面的颜色分别为黑色和白色,游戏的每一轮选择一个格子翻动,翻动该格子 ...
- poj1753,Flip Game,ArrayDeque<Node>
Flip Game Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 30449 Accepted: 13232 Descr ...
- POJ1753 Flip Game(bfs、枚举)
链接:http://poj.org/problem?id=1753 Flip Game Description Flip game is played on a rectangular 4x4 fie ...
- POJ1753——Flip Game
Flip Game Description Flip game is played on a rectangular 4x4 field with two-sided pieces placed on ...
- POJ-1753 Flip Game---二进制枚举子集
题目链接: https://vjudge.net/problem/POJ-1753 题目大意: 有4*4的正方形,每个格子要么是黑色,要么是白色,当把一个格子的颜色改变(黑->白或者白-> ...
- POJ-1753 Flip Game (BFS+状态压缩)
Description Flip game is played on a rectangular 4x4 field with two-sided pieces placed on each of i ...
- POJ1753 Flip Game(位运算+暴力枚举)
Flip game is played on a rectangular 4x4 field with two-sided pieces placed on each of its 16 square ...
- poj1753 Flip Game —— 二进制压缩 + dfs / bfs or 递推
题目链接:http://poj.org/problem?id=1753 Flip Game Time Limit: 1000MS Memory Limit: 65536K Total Submis ...
- [POJ1753]Flip Game(异或方程组,高斯消元,枚举自由变量)
题目链接:http://poj.org/problem?id=1753 题意:同上. 这回翻来翻去要考虑自由变元了,假设返回了自由变元数量,则需要枚举自由变元. /* ━━━━━┒ギリギリ♂ eye! ...
随机推荐
- DOM的基本属性
结构和内容属性1.1 nodeType1.2 nodeName, tagName1.3 innerHTML1.4 innerHTML pitFalls1.5 nodeValue 总结DOM节点是一个对 ...
- socket网络编程
一.客户端/服务器架构 C/S架构,包括 1.硬件C/S架构(打印机) 2.软件C/S架构(Web服务) 最常用的软件服务器就是Web服务器,一台机器里放了一些网页或Web应用程序,然后启动服务,这样 ...
- CSS 的overflowhidden 属性详细解释
overflow:hidden这个CSS样式是大家常用到的CSS样式,但是大多数人对这个样式的理解仅仅局限于隐藏溢出,而对于清除浮动这个含义不是很了解. 一提到清除浮动,我们就会想到另外一个 ...
- git简单命令
1. git status(不代参数) -- 查看本地修改过的文件 git status -s (简洁) 2. git add -- 添加到暂存区 3. git commit -m '提交的mess ...
- 【STL】优先队列priority_queue详解+OpenJudge-4980拯救行动
一.关于优先队列 队列(queue)这种东西广大OIer应该都不陌生,或者说,队列都不会你还学个卵啊(╯‵□′)╯︵┻━┻咳咳,通俗讲,队列是一种只允许从前端(队头)删除元素.从后端(队尾)插入元素的 ...
- WPF 中 InitializeComponent 不存在解决方案
部门给了一个WPF应用,但是之前没学过,所以再用vs2015创建测试程序的时候,竟然报了错,一创建项目就报错的程序还真不多.大概就是 InitializeComponent不存在吧.所以在网上看了很多 ...
- dubbo(转载)
1. Dubbo是什么? Dubbo是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案.简单的说,dubbo就是个服务框架,如果没有分布式的需求,其实是不需 ...
- FontMetrics属性的介绍
1.基准点是baseline 2.ascent:是baseline之上至字符最高处的距离 3.descent:是baseline之下至字符最低处的距离 4.leading:是上一行字符的descent ...
- 关于composer安装插件时候提示找不到fxp插件时候的解决办法
如果你在某个目录使用composer.phar,而且在别的目录页使用了composer,并没有全局安装composer的时候,不同目录之间的可能会互相干扰从而报错 root@tyr:/var/www/ ...
- jQuery size()函数
size() 函数 函数用于返回当前jQuery对象封装的元素个数. 语法 jQueryObject.size( ) 返回值 Number类型 返回该jQuery对象封装的DOM元素的个数. 实例说明 ...