POJ 1753 Flip Game
Posted liuzhenhao
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ 1753 Flip Game相关的知识,希望对你有一定的参考价值。
题面
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).
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.
题意
给出一个4*4的01矩阵,每次可以选择一个点,将它本身和上下左右四个点的分别 ^ 1 ,最少需要多少步能将矩阵全变成0或者1
分析
首先通过观察可得,对于一个位置,只有两种可能,选择或者略过,那么显而易见可以得到一个最暴力的枚举,对于每个点的两种可能dfs,时间复杂度是2的次方级别,由于一共有16个位置,2的16次方可以过
如果是5*5的呢?先前的枚举必然超时,那么我们发现,如果确定了第一行的选择方法,第二行开始就只有唯一解,譬如一个点(2,4),如果(1,4)是1,那么必然要选择这个点,因为后面的点都不会影响到(1,4)这个点了。那么最终方案的可行度如何判断呢?很简单,只要for一遍最后一行是否满足就可以的,时间复杂度大大降低。
CODE
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> using namespace std; #define inf 0x3f3f3f3f char s[5][5]; int a[5][5],c[5][5]; int ans=inf; void doit(int h,int pos) c[h-1][pos]^=1,c[h+1][pos]^=1,c[h][pos-1]^=1; c[h][pos]^=1,c[h][pos+1]^=1; //改变点权 int main() for(int i=1;i<=4;++i) for(int j=1;j<=4;++j) scanf(" %c",&s[i][j]); a[i][j]=(s[i][j]==\'b\'?1:0); for(int i=0;i<(1<<4);++i) int cnt=0,flag=1; for(int j=1;j<=4;++j) for(int k=1;k<=4;++k) c[j][k]=a[j][k]; for(int j=1;j<=4;++j) if(i&(1<<(j-1))) doit(1,j),++cnt; for(int j=2;j<=4;++j) for(int k=1;k<=4;++k) if(!c[j-1][k]) doit(j,k),++cnt; for(int j=1;j<=4;++j) if(!c[4][j]) flag=0;// 全为1 if(flag) ans=min(ans,cnt); cnt=0,flag=1; for(int j=1;j<=4;++j) for(int k=1;k<=4;++k) c[j][k]=a[j][k]; for(int j=1;j<=4;++j) if(i&(1<<(j-1))) doit(1,j),++cnt; for(int j=2;j<=4;++j) for(int k=1;k<=4;++k) if(c[j-1][k]) doit(j,k),++cnt; for(int j=1;j<=4;++j) if(c[4][j]) flag=0;//全为0 if(flag) ans=min(ans,cnt); if(ans<inf) printf("%d\\n",ans); else puts("Impossible"); return 0;
以上是关于POJ 1753 Flip Game的主要内容,如果未能解决你的问题,请参考以下文章