学习随笔——POJ题目1753:Flip Game解答

本题题目链接:http://poj.org/problem?id=1753

题目截图如下:

 

 题目大意:在4*4棋盘上有黑白子若干,现需要翻动若干次棋盘上的棋子实现棋盘上的棋子全白或全黑。翻动的规则是:当翻动某一棋子时,其上下左右棋子也需被翻动。求翻动的最小次数,如果无法实现,则需要输出提示信息“Impossible”。

一道枚举的题目,根据分析,我们很容易知道同一个位置的棋子翻动两次与未翻动的状态相同,所以每个位置的棋子我们就可简化为翻动与不翻动两种状态。这样只需确定16个位置的翻动状况即可。同样的,如果最后翻动次数大于16我们可以判定为不存在一种翻动的可行方案。

先放上代码,之后会对递归过程进行详细讲解:

复制代码
 1 #include <stdio.h>
 2 #include <iostream>
 3 using namespace std;
 4 int mem[16] = {0};//化二维为一维的数组 
 5 int ans = 100;//最后返回的回答
 6 void change (int pos){
 7     int x = pos/4;//判断边界条件 
 8     int y = pos%4;//判断边界条件 
 9     mem[pos] = !mem[pos];//先改变目标点 
10     if (x>0)
11         mem[pos-4] = !mem[pos-4];
12     if (x<3)
13         mem[pos+4] = !mem[pos+4];
14     if (y>0)
15         mem[pos-1] = !mem[pos-1];
16     if (y<3)
17         mem[pos+1] = !mem[pos+1]; 
18 }//pos为要改变的点的坐标
19 bool Judge (){
20     for (int i = 0;i<15;i++){
21         if (mem[i] != mem[i+1])
22             return false;
23     }
24     return true;
25 }//判断是否实现预定目标 
26 void Enum (int pos,int count){
27     if (Judge())
28         if (count < ans){
29             ans = count;
30             return ;
31         }
32     if (pos >= 16)
33         return ;
34     change (pos);
35     Enum (pos+1,count+1);
36     change (pos);
37     Enum (pos+1,count);
38     return ;
39 }
40 int main (int argc,char *argv[]){
41     char start;
42     for (int i=0;i<16;i++){
43         cin>>start;
44         if (start=='b'){
45             mem[i]=1;
46         }
47     }
48     Enum (0,0);
49     if (ans==100)
50         printf("Impossible");
51     else
52         printf("%d",ans);
53     return 0;
54 }
复制代码

对递归部分的讲解:

1 change (pos);
2 Enum (pos+1,count+1);
3 change (pos);//复位操作
4 Enum (pos+1,count);

      我对于这四条语句的理解是,我们把它理解为一种状态的转换:每一个位置有翻与不翻两种状态,其中1、2两句即表示该位置棋子翻转,并将该状态输入函数的过程。第三句实际上实现了一种“复位”操作,将原来翻转的棋子再翻转回来,再将该位置棋子未翻转的状态输入函数。或者我们更进一步理解,每个点的翻转与否构成了一个二叉树,我们找到最小值的过程就是对这个树进行深度遍历的过程。事实上,上述语句改编为以下形式亦可。

1 Enum (pos+1,count);
2 change (pos);
3 Enum (pos+1,count+1);
4 change (pos);//复位操作

 

posted @   Johnson-Hugo  阅读(55)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
点击右上角即可分享
微信分享提示