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

Description

Flip game is played on a rectangular 4x4 field with two-sided pieces placed on each of its 16 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:

  1. Choose any one of the 16 pieces.
  2. 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 4 lines with 4 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 0. If it‘s impossible to
achieve the goal, then write the word "Impossible" (without quotes).

Sample Input

bwwb
bbwb
bwwb
bwww

Sample Output

4

题目大意:在一个4x4的棋盘上,摆满了黑白两种颜色的棋子。当翻转一颗棋子的时候,与它相邻的上下左右四个棋子也随之翻转。问将整个棋盘置为同一种颜色最少需要翻转几次。题目分析:这道题的数据量不大且固定不变,2^16个状态,又因为让找最小步骤数,所以就敲定用BFS。接下来就是状态如何表示了,很显然了,4行用四个不超过16的二进制数表示即可。至于状态转移,用位运算异或就能轻松完成。

代码如下:

  1 # include<iostream>
  2 # include<cstdio>
  3 # include<queue>
  4 # include<cstring>
  5 # include<algorithm>
  6 using namespace std;
  7 struct node
  8 {
  9     int a,b,c,d,t;
 10     node(){}
 11     node(int a1,int b1,int c1,int d1,int t1):a(a1),b(b1),c(c1),d(d1),t(t1){}
 12     bool operator < (const node &a) const {
 13         return t>a.t;
 14     }
 15 };
 16 char p[8][8];
 17 int vis [16][16][16][16];
 18 void bfs()
 19 {
 20     int temp[4],a,b,c,d;
 21     for(int i=0;i<4;++i){
 22         temp[i]=0;
 23         for(int j=0;j<4;++j){
 24             if(p[i][j]==‘b‘)
 25                 temp[i]=temp[i]*2+1;
 26             else
 27                 temp[i]=temp[i]*2+0;
 28         }
 29     }
 30     priority_queue<node>q;
 31     memset(vis,0,sizeof(vis));
 32     vis[temp[0]][temp[1]][temp[2]][temp[3]]=1;
 33     q.push(node(temp[0],temp[1],temp[2],temp[3],0));
 34     while(!q.empty()){
 35         node u=q.top();
 36         q.pop();
 37         if(u.a==15&&u.b==15&&u.c==15&&u.d==15){
 38             printf("%d\n",u.t);
 39             return ;
 40         }
 41         if(!u.a&&!u.b&&!u.c&&!u.d){
 42             printf("%d\n",u.t);
 43             return ;
 44         }
 45         for(int i=0;i<4;++i){
 46             a=u.a,b=u.b,c=u.c,d=u.d;
 47             a^=(1<<i);
 48             b^=(1<<i);
 49             if(i>0)
 50                 a^=(1<<(i-1));
 51             if(i<3)
 52                 a^=(1<<(i+1));
 53             if(!vis[a][b][c][d]){
 54                 vis[a][b][c][d]=1;
 55                 q.push(node(a,b,c,d,u.t+1));
 56             }
 57         }
 58         for(int i=0;i<4;++i){
 59             a=u.a,b=u.b,c=u.c,d=u.d;
 60             b^=(1<<i);
 61             a^=(1<<i);
 62             c^=(1<<i);
 63             if(i>0)
 64                 b^=(1<<(i-1));
 65             if(i<3)
 66                 b^=(1<<(i+1));
 67             if(!vis[a][b][c][d]){
 68                 vis[a][b][c][d]=1;
 69                 q.push(node(a,b,c,d,u.t+1));
 70             }
 71         }
 72         for(int i=0;i<4;++i){
 73             a=u.a,b=u.b,c=u.c,d=u.d;
 74             c^=(1<<i);
 75             b^=(1<<i);
 76             d^=(1<<i);
 77             if(i>0)
 78                 c^=(1<<(i-1));
 79             if(i<3)
 80                 c^=(1<<(i+1));
 81             if(!vis[a][b][c][d]){
 82                 vis[a][b][c][d]=1;
 83                 q.push(node(a,b,c,d,u.t+1));
 84             }
 85         }
 86         for(int i=0;i<4;++i){
 87             a=u.a,b=u.b,c=u.c,d=u.d;
 88             d^=(1<<i);
 89             c^=(1<<i);
 90             if(i>0)
 91                 d^=(1<<(i-1));
 92             if(i<3)
 93                 d^=(1<<(i+1));
 94             if(!vis[a][b][c][d]){
 95                 vis[a][b][c][d]=1;
 96                 q.push(node(a,b,c,d,u.t+1));
 97             }
 98         }
 99     }
100     printf("Impossible\n");
101 }
102 int main()
103 {
104     for(int i=0;i<4;++i)
105         scanf("%s",p[i]);
106     bfs();
107     return 0;
108 }

时间: 2024-12-30 12:47:31

POJ-1753 Flip Game (BFS+状态压缩)的相关文章

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 16 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 f

[ACM] POJ 1753 Flip Game (枚举,BFS,位运算)

Flip Game Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 29921   Accepted: 12975 Description Flip game is played on a rectangular 4x4 field with two-sided pieces placed on each of its 16 squares. One side of each piece is white and the

POJ 1753 Flip Game (高斯消元 枚举自由变元求最小步数)

题目链接 题意:4*4的黑白棋,求把棋全变白或者全变黑的最小步数. 分析:以前用状态压缩做过. 和上题差不多,唯一的不同是这个终态是黑棋或者白棋, 但是只需要把给的初态做不同的两次处理就行了. 感觉现在还只是会套模板,不能独立的思考,好伤心.... 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 #include <cmath&g

ACM/ICPC 之 BFS+状态压缩(POJ1324(ZOJ1361))

求一条蛇到(1,1)的最短路长,题目不简单,状态较多,需要考虑状态压缩,ZOJ的数据似乎比POj弱一些 POJ1324(ZOJ1361)-Holedox Moving 题意:一条已知初始状态的蛇,求其到(1,1)的最短路长 题解:开始做的时候用BFS暴力做了一次,结果RE了,后来看了其他的题解和discuss才转向状态压缩.也看到有人用A*做出来了. 现在简要介绍一下状态压缩的思路: 由于蛇身最长只有8,可以利用两条相邻蛇身坐标确定其相对方向(四个方向),两位二进制可以表示 这样 一个蛇头坐标+

hdu--1429--胜利大逃亡(续) (bfs+状态压缩)

胜利大逃亡(续) Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 8560    Accepted Submission(s): 3071 Problem Description Ignatius再次被魔王抓走了(搞不懂他咋这么讨魔王喜欢)-- 这次魔王汲取了上次的教训,把Ignatius关在一个n*m的地牢里,并在地牢的某些地方安装了带

hdoj 5094 Maze 【BFS + 状态压缩】 【好多坑】

Maze Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 100000/100000 K (Java/Others) Total Submission(s): 901    Accepted Submission(s): 314 Problem Description This story happened on the background of Star Trek. Spock, the deputy captain of St

poj 3254 Corn Fields ,状态压缩DP

题目链接 题意: 一个矩阵里有很多格子,每个格子有两种状态,可以放牧和不可以放牧,可以放牧用1表示,否则用0表示,在这块牧场放牛,要求两个相邻的方格不能同时放牛,即牛与牛不能相邻.问有多少种放牛方案(一头牛都不放也是一种方案) state[i] 表示对于一行,保证不相邻的方案 状态:dp[i][ state[j] ]  在状态为state[j]时,到第i行符合条件的可以放牛的方案数 状态转移:dp[i][ state[j] ] =Sigma dp[i-1][state'] (state'为符合条

hdu2209翻纸牌游戏(bfs+状态压缩)

Problem Description 有一种纸牌游戏,很有意思,给你N张纸牌,一字排开,纸牌有正反两面,开始的纸牌可能是一种乱的状态(有些朝正,有些朝反),现在你需要整理这些纸牌.但是麻烦的是,每当你翻一张纸牌(由正翻到反,或者有反翻到正)时,他左右两张纸牌(最左边和最右边的纸牌,只会影响附近一张)也必须跟着翻动,现在给你一个乱的状态,问你能否把他们整理好,使得每张纸牌都正面朝上,如果可以,最少需要多少次操作. Input 有多个case,每个case输入一行01符号串(长度不超过20),1表

POJ 1753 Flip Game (DFS + 枚举)

题目:http://poj.org/problem?id=1753 这个题在开始接触的训练计划的时候做过,当时用的是DFS遍历,其机制就是把每个棋子翻一遍,然后顺利的过了,所以也就没有深究. 省赛前一次做PC2遇到了几乎一模一样的题,只不过是把棋盘的界限由4X4改为了5X5,然后一直跑不出结果来,但是当时崔老湿那个队过了,在最后总结的时候,崔老湿就说和这个题一样,不过要枚举第一行进行优化. 我以为就是恢复第一行然后第二行以此类推,不过手推一下结果是6不是4,就知道这个有问题. 问了崔老湿,问了+

POJ 1038 Bugs Integrated, Inc. 状态压缩DP

题目来源:1038 Bugs Integrated, Inc. 题意:最多能放多少个2*3的矩形 思路:状态压缩DP啊 初学 看着大牛的代码搞下来的  总算搞懂了 接下来会更轻松吧 3进制代表前2行的状态(i行和i-1行)1代表i-1行占位 2代表i行占位 i-1不管有没有占位都不会影响的0代表i行和i-1行都空闲 然后枚举状态dfs更新状态 话说就不能没写深搜了 有点不会了 #include <cstdio> #include <cstring> #include <alg