POJ-1753 Flip Game

英文原文
Flip Game
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 48708 Accepted: 20740
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:
Choose any one of the 16 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 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 Europ
翻转游戏
原题链接
时间限制:1000毫秒 内存限制:65536 k
总提交:48708年 接受:20740年
描述

翻转游戏在一个矩形的4 x4领域双边块放置在16个方格。每一块的一侧是白色的,另一个是黑色和每一块躺是黑色或白色的一面。每一轮抛3到5块,从而改变上面的颜色从黑到白,反之亦然。选择了每轮的部分按照下列规则:
选择任何一个16块。
翻转所选块所有相邻块向左,向右,顶部,底部的选择(如果有)。

考虑下面的位置作为一个例子:

bwbw
wwww
bbwb
bwwb
这里“b”代表作品躺在黑色的一面,“w”表示碎片躺在白色的一面。如果我们选择翻转从第三行第一块(这个选择是图片所示),然后该领域将成为:

bwbw
bwww
wwwb
wwwb
游戏的目标是把所有块白色一面或块黑色的一面朝上。你要编写一个程序,将搜索所需要的最小数量的轮实现这一目标。
输入

4线和4字符的输入由“w”或“b”,表示游戏领域的位置。
输出

写入输出文件一个整数——实现目标所需的最小数量的轮的游戏从给定的位置。如果目标是最初实现,然后写0。如果它是不可能实现的目标,然后写“Impossible”这个词(没有引号)。
样例输入

bwwb
bbwb
bwwb
bwww
样例输出

4

2000年欧洲东北部

题解
这题和之前做过的某题很相似,但是求的东西不一样,那题求的是能否全翻过来,这里求最小次数。

题目中很明确的,4×4 的wb矩阵,所以果断用二进制压位来记录状态,先把矩阵分层割开,然后接成一条线,再把每位上的 w 和 b 看成二进制中的 0 或 1。这个二进制数的大小范围是 0 0 ~2171,大小还可以,所以可以刷 bfs,用 hash 数组记录走到每个状态的最短距离,最后如果可以走到 0 0 2171 的状态,那么有解,否则无解。

我写的是枚举状态的。也就是枚举一个 01 矩阵,每隔的 0 和 1 表示这个格子是否要翻面(翻两次等于没翻),和上面同理,压成一个二进制数来枚举。

代码

#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=1<<17;
int q,ans,flg[5][2]={{0,0},{1,0},{0,1},{-1,0},{0,-1}};
char s[5][6];
int get(int s){return s? (s&1)+get(s>>1):0;}
void check(int x,int y,int &s)
{
    if (0<=x&&x<=3&&0<=y&&y<=3) s^=1<<(x<<2)+y;
}
void work()
{
    ans=1e9;
    for (int i=0;i<1<<16;i++)
    {
        int s=i,sum,x=q;if ((sum=get(s))>=ans) continue;
        for (int j=0;j<4;j++)
        for (int k=0;k<4;k++)
          {if (s&1) for (int t=0;t<5;t++) check(j+flg[t][0],k+flg[t][1],x);s>>=1;}
        if (x==0||x==(1<<16)-1) ans=sum;
    }
    if (ans==1e9) printf("Impossible");else printf("%d",ans);
}
int main()
{
    for (int i=0;i<4;i++) scanf("%s",s[i]);
    for (int i=0;i<4;i++)
        for (int j=0;j<4;j++)
            if (s[i][j]=='b') q+=1<<(i<<2)+j;
    work();
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值