poj 1753 Flip Game(bfs状态压缩 或 dfs枚举)
Description
Flip game is played on a rectangular 4x4 field with two-sided pieces placed on each of its squares. One side of each piece is white and the other one is black and each piece is lying either it's black or white side up. Each round you flip 3 to 5 pieces, thus changing the color of their upper side from black to white and vice versa. The pieces to be flipped are chosen every round according to the following rules:
Choose any one of the pieces.
Flip the chosen piece and also all adjacent pieces to the left, to the right, to the top, and to the bottom of the chosen piece (if there are any).

Consider the following position as an example: bwbw
wwww
bbwb
bwwb
Here "b" denotes pieces lying their black side up and "w" denotes pieces lying their white side up. If we choose to flip the 1st piece from the 3rd row (this choice is shown at the picture), then the field will become: bwbw
bwww
wwwb
wwwb
The goal of the game is to flip either all pieces white side up or all pieces black side up. You are to write a program that will search for the minimum number of rounds needed to achieve this goal.
Input
The input consists of lines with characters "w" or "b" each that denote game field position.
Output
Write to the output file a single integer number - the minimum number of rounds needed to achieve the goal of the game from the given position. If the goal is initially achieved, then write . If it's impossible to achieve the goal, then write the word "Impossible" (without quotes).
Sample Input
bwwb
bbwb
bwwb
bwww
Sample Output
Source
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<math.h>
#include<algorithm>
#include<queue>
#include<set>
#include<bitset>
#include<map>
#include<vector>
#include<stdlib.h>
using namespace std;
#define max(a,b) (a) > (b) ? (a) : (b)
#define min(a,b) (a) < (b) ? (a) : (b)
#define ll long long
#define eps 1e-10
#define MOD 1000000007
#define N 1000000
#define inf 1e12 int vis[(<<)];
struct Node{
int val;
int t; }st;
int mp[]={
,,,,,,,,,,,,,,,
};
void bfs(){
queue<Node>q;
q.push(st);
Node t1,t2;
vis[st.val]=;
while(!q.empty()){
t1=q.front();
q.pop();
if(t1.val== || t1.val==((<<)-)){
printf("%d\n",t1.t);
return ;
}
for(int i=;i<;i++){
t2=t1;
t2.val^=mp[i];
if(vis[t2.val]) continue;
vis[t2.val]=;
t2.t++;
q.push(t2);
}
}
printf("Impossible\n");
}
int main()
{
char s[];
int ans=;
int num=;
for(int i=;i<;i++){
scanf("%s",s);
for(int j=;j<;j++){
if(s[j]=='b'){
ans+=(<<num);
}
num--;
}
}
st.val=ans;
st.t=;
memset(vis,,sizeof(vis));
bfs(); return ;
}
思路:仔细考虑,可以发现,一个位置的棋子,要么保持原状不变,要么改变一次。因为改变偶数次和不改变的效果是一样的,改变奇数次和改变1次的效果是一样的。也就是说,达到最后颜色都一样的状态,某个位置的棋子,要么改变一次,要么一次也不改变。所以求最少经过多少步的改变,可以转化为最少需要改变多少个棋子。因为数据范围小,总共16个棋子,所以我们可以枚举。
我们可以判断改变0个,改变1个,改变2个,,,改变16个。改变x个,就是从16个元素中选x个的过程,可以用dfs实现。如果一直到最后改变16个都不行,则输出“Impossible”即可。
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<math.h>
#include<algorithm>
#include<queue>
#include<set>
#include<bitset>
#include<map>
#include<vector>
#include<stdlib.h>
using namespace std;
#define max(a,b) (a) > (b) ? (a) : (b)
#define min(a,b) (a) < (b) ? (a) : (b)
#define ll long long
#define eps 1e-10
#define MOD 1000000007
#define N 26
#define inf 1e12
int mp[][];
int newMp[][];
int newRecord[N];
int dirx[]={,,-,};
int diry[]={-,,,};
int flag;
int vis[N];
void judge(int cnt){
for(int i=;i<;i++){
for(int j=;j<;j++){
newMp[i][j]=mp[i][j];
}
}
for(int i=;i<cnt;i++){
int x=newRecord[i]/;
int y=newRecord[i]-x*;
newMp[x][y]=!newMp[x][y];
for(int j=;j<;j++){
int newX=x+dirx[j];
int newY=y+diry[j];
if(newX< || newX>= || newY< || newY>=) continue;
newMp[newX][newY]=!newMp[newX][newY];
}
}
int ans=;
for(int i=;i<;i++){
for(int j=;j<;j++){
if(newMp[i][j]){
ans++;
}
}
}
if(ans== || ans==){
flag=;
}
}
void dfs(int st,int num,int cnt){
if(num==cnt){
judge(cnt);
return;
} for(int i=st;i<;i++){
if(!vis[i]){
vis[i]=;
newRecord[num]=i;
dfs(i,num+,cnt);
if(flag)
return;
vis[i]=;
}
} }
int main()
{
char s[];
for(int i=;i<;i++){
scanf("%s",s);
for(int j=;j<;j++){
if(s[j]=='b'){
mp[i][j]=;
}
else{
mp[i][j]=;
}
}
}
flag=;
for(int i=;i<=;i++){//改变多少个可以达到目的
memset(vis,,sizeof(vis)); dfs(,,i);
if(flag){
printf("%d\n",i);
break;
}
}
if(flag==){
printf("Impossible\n");
} return ;
}
poj 1753 Flip Game(bfs状态压缩 或 dfs枚举)的更多相关文章
- POJ 1753 Flip Game (状态压缩 bfs+位运算)
Flip game is played on a rectangular 4x4 field with two-sided pieces placed on each of its 16 square ...
- BFS+状态压缩DP+二分枚举+TSP
http://acm.hdu.edu.cn/showproblem.php?pid=3681 Prison Break Time Limit: 5000/2000 MS (Java/Others) ...
- ACM/ICPC 之 BFS+状态压缩(POJ1324(ZOJ1361))
求一条蛇到(1,1)的最短路长,题目不简单,状态较多,需要考虑状态压缩,ZOJ的数据似乎比POj弱一些 POJ1324(ZOJ1361)-Holedox Moving 题意:一条已知初始状态的蛇,求其 ...
- 枚举 POJ 1753 Flip Game
题目地址:http://poj.org/problem?id=1753 /* 这题几乎和POJ 2965一样,DFS函数都不用修改 只要修改一下change规则... 注意:是否初始已经ok了要先判断 ...
- HDU1429+bfs+状态压缩
bfs+状态压缩思路:用2进制表示每个钥匙是否已经被找到.. /* bfs+状态压缩 思路:用2进制表示每个钥匙是否已经被找到. */ #include<algorithm> #inclu ...
- BFS+状态压缩 hdu-1885-Key Task
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1885 题目意思: 给一个矩阵,给一个起点多个终点,有些点有墙不能通过,有些点的位置有门,需要拿到相应 ...
- BFS+状态压缩 HDU1429
胜利大逃亡(续) Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total S ...
- hdoj 5094 Maze 【BFS + 状态压缩】 【好多坑】
Maze Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 100000/100000 K (Java/Others) Total Sub ...
- poj - 3254 - Corn Fields (状态压缩)
poj - 3254 - Corn Fields (状态压缩)超详细 参考了 @外出散步 的博客,在此基础上增加了说明 题意: 农夫有一块地,被划分为m行n列大小相等的格子,其中一些格子是可以放牧的( ...
随机推荐
- 图论专题训练1-D(K步最短路,矩阵连乘)
题目链接 /* *题目大意: *求出从i到j,刚好经过k条边的最短路; * *矩阵乘法的应用之一(国家队论文): *矩阵乘法不满足交换律,矩阵乘法满足结合律; *给定一个有向图,问从A点恰好走k步(允 ...
- ListView之BaseAdapter
BaseAdapter可以实现自定义的丰富子项视图,本文实现如下所示结果: 实现代码: /* ListView :列表 BaseAdapter 通用的基础适配器 * * */ public class ...
- Eat Candy(暴力,水)
Eat Candy Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 8 Solved: 6[Submit][Status][Web Board] Des ...
- Spark1.0.0 分布式环境搭建
软件版本号例如以下: Hostname IP Hadoop版本号 Hadoop 功能 系统 master 192.168.119.128 1.1.2 namenode jdk1.6+hadoop+sc ...
- vs2010 正式版官方下载地址
北京时间2010年4月12日12:00,微软Visual Studio 2010 正式版提供官方下载,眼下有三个版本号,Professional/Premium/Ultimate. 注意原页面的链接R ...
- CSS - 关于li中图文混排不能垂直居中的问题
图片和文字一起放在li标签下不能同时垂直居中 解决办法: 1.设置图片的position:absolute; 2.把文字加上span标签: span{ height:30px;line-heigh ...
- contentSize、contentInset和contentOffset
contentSize.contentInset和contentOffset 是 scrollView三个基本的属性. contentSize: The size of the content vie ...
- Spark RDD设计学习笔记
本文档是学习RDD经典论文<Resilient Distributed Datasets: A Fault-Tolerant Abstraction for In-Memory Cluster ...
- (原)在ubuntu 中安装 swi prolog 和 简单的使用
参考网址:http://www0.cs.ucl.ac.uk/staff/mahmed/teaching/intro.html 参考网址:http://www.swi-prolog.org/build/ ...
- 求a,b在区间上的公倍数个数
给你两个数 a,b.问你区间 [1,N]中都是有多少个数是a,b的公倍数.当数据很大的时候,遍历肯定会超时.其实,我们可以首先求出 lcm(a,b).因为我们知道(a,b)公倍数都是它最小公倍数的倍数 ...