Flip Game
Time Limit: 1000 MS Memory Limit: 65536 KB
64-bit integer IO format: %I64d , %I64u Java class name: Main
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********************************************************分割线**********************************************************************************************************************************学校竟然把它放到枚举的练习题里,我都惊呆了,不过仔细一想的确是一道枚举的题,但我是用动态规划的思想所以我又把它算是动态规划了,
1 //动态规划的思想,每一个点都有翻不翻两种情况,复杂度为2^n,需注意的是scanf的问题 2 #include<stdio.h> 3 #include<string.h> 4 using namespace std; 5 bool chess[6][6]={false}; 6 int step; 7 bool flag; 8 int r[5]={-1,1,0,0,0}; 9 int c[5]={0,0,-1,1,0};//(0,0)biaoshizijihenhaoyonga 10 bool isOver(){//jianchashifoujieshu 11 int i,j; 12 for(i=1;i<5;i++) 13 for(j=1;j<5;j++) 14 if(chess[i][j]!=chess[1][1]) 15 return false; 16 return true; 17 } 18 void flip(int row,int col){//反转辞典对应可以翻转的所有点 19 for(int i=0;i<5;i++) 20 chess[row+r[i]][col+c[i]]=!chess[row+r[i]][col+c[i]]; 21 } 22 void dfs(int row,int col,int deep){ 23 if(deep==step){ 24 // printf("HHH%d==%dflag==%d\n",deep,step,flag); 25 flag=isOver(); 26 return ; 27 } 28 29 if(flag||row==5) return ; 30 flip(row,col);//翻转 31 if(col<4) dfs(row,col+1,deep+1); 32 else dfs(row+1,1,deep+1); 33 flip(row,col); 34 if(col<4) dfs(row,col+1,deep); 35 else dfs(row+1,1,deep); 36 return ; 37 } 38 int main() 39 { 40 int i,j; 41 char temp; 42 // memset(chess,0,sizeof(chess)); 43 for(int i=1;i<5;i++){ 44 for(int j=1;j<5;j++){ 45 scanf("%c",&temp);//cin不会接受换行符,但scanf会连换行符一起读入 46 if(temp==‘b‘) chess[i][j]=true; 47 } 48 getchar(); 49 } 50 /*for(i=1;i<5;i++) 51 for(j=1;j<5;j++) 52 printf("%d ",chess[i][j]);*/ 53 for(step=0;step<=16;step++){//最大是16次翻转,因为16次之后的每次翻转都会造成和不翻那个格子相同的情况。 54 dfs(1,1,0); 55 // printf("STEP=%d\n",step); 56 if(flag) break; 57 } 58 if(flag) printf("%d\n",step); 59 else printf("Impossible\n"); 60 61 }
这里是以翻几个棋子为dp线索的,和子集生成好像啊!每一个都是翻不翻,而子集生成是每一个都取不取以个数为线索寻找结束条件。
我暂时理解为暴力,dp,深搜法(我还是个小白啊,会的少,勿怪,暂时对知识点的总结还不是很成熟)