标签:NPU eof ret xmlns ++ 第一个 overflow rect int
Descrption
翻转游戏是在一个 4×4
的正方形上进行的,在正方形的 16 个格上每个格子都放着一个双面的物件。每个物件的两个面,一面是白色,另一面是黑色,每个物件要么白色朝上,要么黑色朝上,每一轮你只能翻 3 至 5
个物件,从而由黑到白的改变这些物件上面的颜色,反之亦然。每一轮被选择翻转的物件遵循以下规则:
以下为例:
bwbw
wwww
bbwb
bwwb
表示该格子放的物件黑色面朝上、w
bwbw
bwww
wwwb
wwwb
游戏的目标是翻转到所有的物件白色朝上或黑色朝上。你的任务就是写一个程序来求最少的翻转次数来实现这一目标。
Input
行,每行 4 个字符,每个字符 w 或 b
Output
0
,如果不可能实现目标就输出: ISample Input
bwwb
bbwb
bwwb
bwww
Sample Output
4
Hint
根据数据范围可知,本题可以暴力枚举。
#include <cstdio> #include <cstring> #include <cmath> #include <algorithm> const int Inf=1<<16; int cnt,ans=Inf; char s[5][5],ss[5][5]; void C(char &a){ if(a==‘w‘)a=‘b‘; else if(a==‘b‘)a=‘w‘; } void F(int x,int y){ cnt++;//翻转一次次数加1 C(ss[x][y]); C(ss[x-1][y]); C(ss[x][y-1]); C(ss[x+1][y]); C(ss[x][y+1]); } void W(int x,char y){//目标是全翻为y memcpy(ss,s,sizeof s);//拷贝原数组 cnt=0; for(int i=1;i<=4;++i){//按照形参中规定的第一行翻转后的状态来翻转,枚举第一行每一列 if(x&(1<<(i-1))){//若该点需翻转(与形参中y不同) F(1,i);//就主动翻转 } } for(int i=2;i<=4;++i){//枚举2~4行 for(int j=1;j<=4;++j){//枚举每一列 if(ss[i-1][j]!=y){//若上一行不是y的话 F(i,j);//就需要本行这一列来翻转从而是上面的那个字符被动变为y } } }//循环结束后前3行全已经变为y了 for(int i=1;i<=4;++i){ if(ss[4][i]!=y)return; } ans=ans>cnt?cnt:ans;//若都能变为y,则第一行按x状态翻转所需要的步数对最终结果有贡献 } int main(){ for(int i=1;i<=4;++i){ scanf("%s",s[i]+1); } for(int S=0;S<=15;++S){//因为还要翻转第二行,所以第一行翻转后可能是任意状态,在此枚举 W(S,‘w‘);W(S,‘b‘); } if(ans==Inf){ printf("Impossible\n"); }else printf("%d\n",ans); return 0; }
标签:NPU eof ret xmlns ++ 第一个 overflow rect int
原文地址:https://www.cnblogs.com/Lour688/p/13204698.html