Flip Game (poj 1753)枚举+二进制


Flip Game

Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 31031   Accepted: 13500

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

Source

Northeastern Europe 2000

题意:有一个4*4的方格,每个方格中放一粒棋子,这个棋子一面是白色,一面是黑色。游戏规则为每次任选16颗中的一颗,把选中的这颗以及它四周的棋子一并反过来,当所有的棋子都是同一个颜色朝上时,游戏就完成了。现在给定一个初始状态,要求输出能够完成游戏所需翻转的最小次数,如果初始状态已经达到要求输出0。如果不可能完成游戏,输出Impossible。

思路:因为方格只有4*4,直接枚举所有状态,用队列实现:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <string>
#include <map>
#include <stack>
#include <vector>
#include <set>
#include <queue>
#pragma comment (linker,"/STACK:102400000,102400000")
#define maxn 1005
#define MAXN 2005
#define mod 1000000009
#define INF 0x3f3f3f3f
#define pi acos(-1.0)
#define eps 1e-6
typedef long long ll;
using namespace std;

struct node
{
    int x;
    int step;
};

queue<node>Q;
int visit[70000];  //标记状态,是否出现过

int main()
{
    int id;
    char ch;
    id=0;
    memset(visit,0,sizeof(visit));
    for (int i=0;i<4;i++)
    {
        for (int j=0;j<4;j++)
        {
            scanf("%c",&ch);
            if (ch=='b')
                id=id^(1<<(4*i+j));
        }
        getchar();
    }
    if (id==0||id==65535)
    {
        printf("0\n");
        return 0;
    }
    while (!Q.empty())
        Q.pop();
    node st,now;
    st.x=id;
    visit[id]=1;
    st.step=0;
    Q.push(st);
    while (!Q.empty())
    {
        st=Q.front();
        Q.pop();
        if (st.x==0||st.x==65535)
        {
            printf("%d\n",st.step);
            return 0;
        }
        for (int i=0;i<4;i++)
            for (int j=0;j<4;j++)
        {
            now.x=st.x^(1<<(4*i+j));
            if (i>0)
                now.x=now.x^(1<<(4*(i-1)+j));//上
            if (i<3)
                now.x=now.x^(1<<(4*(i+1)+j));//下
            if (j>0)
                now.x=now.x^(1<<(4*i+j-1));//左
            if (j<3)
                now.x=now.x^(1<<(4*i+j+1));//右
            if (!visit[now.x])
            {
                now.step=st.step+1;
                Q.push(now);
                visit[now.x]=1;
            }
        }
    }
    printf("Impossible\n");
    return 0;
}
/*
bwwb
bbwb
bwwb
bwww
*/
时间: 2024-07-28 12:55:41

Flip Game (poj 1753)枚举+二进制的相关文章

POJ 1753 (枚举+DFS)

Flip Game Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 40632   Accepted: 17647 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 枚举+暴搜

很基础的题,但是有很多种搜索姿势,感觉用来入门还是很好的. 题意:有一个4*4的棋盘,棋盘上有黑白格,每一次你可以翻其中的一个格子.一个格子(x,y)如果被翻,它相邻的前后左右四个格子(如果在棋盘上)也要翻转.现在给你一个初始的棋盘状态,问把这个棋盘翻转到全黑或全白的最少次数:若不能达到全黑或全白,输出Impossible. 只有4*4的棋盘,同时格子只有黑白两面.对于同一个格子,翻两次和不翻没有区别.很小的数据量,就是引导人状压之后去暴力做的.但是你可以枚举全部65536种状态不断更新答案:也

POJ 1753(枚举)

1 #include <iostream> 2 #include <cstdio> 3 #include <cmath> 4 #include <cstring> 5 #include <algorithm> 6 #include <queue> 7 #include <stack> 8 #include <vector> 9 using namespace std; 10 char a[6][6]; 11 i

[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(dfs+枚举)

POJ 1753 题意: 输入一个4*4的图像,由黑白两色组成,定义一种操作为:改变某个格子内小球的颜色(黑变白,白变黑),同时其上下左右的格子内小球也将变色.求最少多少次操作能使之成为纯色图案. 思路: 对一个格子操作偶数次等于没有操作,操作奇数次等于操作一次,所以答案在0~16以及impossible之间. 从n=0开始枚举n次操作可能的组成情况,即操作哪几个格子,若某种组合能变图案为纯色则停止. 由于总组合数达到2^16,故枚举组合情况可以用dfs来进行回溯枚举. //还有一种方法是位运算

POJ 1753 Flip Game (DFS + 枚举)

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

poj 1753 Flip Game (bfs + 枚举)

链接:poj 1753 题意:这是翻棋游戏,给定4*4棋盘,棋子一面为黑色(用b表示),另一面为白色(用w表示),问至少要几步可以将棋子翻为全黑或者全白,如不能达到目的,输出"Impossible " 翻转规则:可以选定16个棋子中的任意一个,将其本身以及上下左右相邻的翻转过来 分析:其实每格棋子最多只可以翻转一次(实际是奇数次,但与翻转一次状态一样),只要其中一格重复翻了2次(不论是连续翻动还是不连翻动),那么它以及周边的棋子和没翻动时的状态是一致的,与最初状态未翻转一样,由此就可以

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

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

【POJ 1753】Flip Game

[POJ 1753]Flip Game 二进制+(BFS)暴力枚举 原本用二位字符数组存 发现遍历困难 并且翻动棋子也难办 后来想到一维线性 下标 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 在图中即为 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 预处理出一个数组进行翻转 后来又发现预处理难办 灵光一现 由于只有黑白两色 可用1 0标记 看到1 0想到的当然就是二进制了 并且又做成了个线性 刚好16位二进制 一切迎刃而解 翻转可

[ACM训练] 算法初级 之 基本算法 之 枚举(POJ 1753+2965)

先列出题目: 1.POJ 1753 POJ 1753  Flip Game:http://poj.org/problem?id=1753 Sample Input bwwb bbwb bwwb bwww Sample Output 4 入手竟然没有思路,感觉有很多很多种情况需要考虑,也只能使用枚举方法才能解决了吧~ 4x4的数组来进行数据存储的话操作起来肯定非常不方便,这里借用位压缩的方法来存储状态,使用移位来标识每一个位置的的上下左右的位置操作. 详细看这里. 1.当棋盘状态id为0(全白)或