题意: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的更多相关文章

  1. poj1753 Flip Game(BFS+位压缩)

    题目链接 http://poj.org/problem?id=1753 题意 一个棋盘上有16个格子,按4×4排列,每个格子有两面,两面的颜色分别为黑色和白色,游戏的每一轮选择一个格子翻动,翻动该格子 ...

  2. poj1753,Flip Game,ArrayDeque&lt;Node&gt;

    Flip Game Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 30449   Accepted: 13232 Descr ...

  3. POJ1753 Flip Game(bfs、枚举)

    链接:http://poj.org/problem?id=1753 Flip Game Description Flip game is played on a rectangular 4x4 fie ...

  4. POJ1753——Flip Game

    Flip Game Description Flip game is played on a rectangular 4x4 field with two-sided pieces placed on ...

  5. POJ-1753 Flip Game---二进制枚举子集

    题目链接: https://vjudge.net/problem/POJ-1753 题目大意: 有4*4的正方形,每个格子要么是黑色,要么是白色,当把一个格子的颜色改变(黑->白或者白-> ...

  6. POJ-1753 Flip Game (BFS+状态压缩)

    Description Flip game is played on a rectangular 4x4 field with two-sided pieces placed on each of i ...

  7. POJ1753 Flip Game(位运算+暴力枚举)

    Flip game is played on a rectangular 4x4 field with two-sided pieces placed on each of its 16 square ...

  8. poj1753 Flip Game —— 二进制压缩 + dfs / bfs or 递推

    题目链接:http://poj.org/problem?id=1753 Flip Game Time Limit: 1000MS   Memory Limit: 65536K Total Submis ...

  9. [POJ1753]Flip Game(异或方程组,高斯消元,枚举自由变量)

    题目链接:http://poj.org/problem?id=1753 题意:同上. 这回翻来翻去要考虑自由变元了,假设返回了自由变元数量,则需要枚举自由变元. /* ━━━━━┒ギリギリ♂ eye! ...

随机推荐

  1. DOM的基本属性

    结构和内容属性1.1 nodeType1.2 nodeName, tagName1.3 innerHTML1.4 innerHTML pitFalls1.5 nodeValue 总结DOM节点是一个对 ...

  2. socket网络编程

    一.客户端/服务器架构 C/S架构,包括 1.硬件C/S架构(打印机) 2.软件C/S架构(Web服务) 最常用的软件服务器就是Web服务器,一台机器里放了一些网页或Web应用程序,然后启动服务,这样 ...

  3. CSS 的overflowhidden 属性详细解释

    overflow:hidden这个CSS样式是大家常用到的CSS样式,但是大多数人对这个样式的理解仅仅局限于隐藏溢出,而对于清除浮动这个含义不是很了解.      一提到清除浮动,我们就会想到另外一个 ...

  4. git简单命令

    1. git status(不代参数) -- 查看本地修改过的文件 git status -s (简洁) 2. git add  -- 添加到暂存区 3. git commit -m '提交的mess ...

  5. 【STL】优先队列priority_queue详解+OpenJudge-4980拯救行动

    一.关于优先队列 队列(queue)这种东西广大OIer应该都不陌生,或者说,队列都不会你还学个卵啊(╯‵□′)╯︵┻━┻咳咳,通俗讲,队列是一种只允许从前端(队头)删除元素.从后端(队尾)插入元素的 ...

  6. WPF 中 InitializeComponent 不存在解决方案

    部门给了一个WPF应用,但是之前没学过,所以再用vs2015创建测试程序的时候,竟然报了错,一创建项目就报错的程序还真不多.大概就是 InitializeComponent不存在吧.所以在网上看了很多 ...

  7. dubbo(转载)

    1. Dubbo是什么? Dubbo是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案.简单的说,dubbo就是个服务框架,如果没有分布式的需求,其实是不需 ...

  8. FontMetrics属性的介绍

    1.基准点是baseline 2.ascent:是baseline之上至字符最高处的距离 3.descent:是baseline之下至字符最低处的距离 4.leading:是上一行字符的descent ...

  9. 关于composer安装插件时候提示找不到fxp插件时候的解决办法

    如果你在某个目录使用composer.phar,而且在别的目录页使用了composer,并没有全局安装composer的时候,不同目录之间的可能会互相干扰从而报错 root@tyr:/var/www/ ...

  10. jQuery size()函数

    size() 函数 函数用于返回当前jQuery对象封装的元素个数. 语法 jQueryObject.size( ) 返回值 Number类型 返回该jQuery对象封装的DOM元素的个数. 实例说明 ...