博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
POJ 1753 Flip Game (递归枚举)
阅读量:7039 次
发布时间:2019-06-28

本文共 3106 字,大约阅读时间需要 10 分钟。

POJ 1753,题目链接,翻译一下整个题目的大概意思:

有4*4的正方形,每个格子要么是黑色,要么是白色,当把一个格子的颜色改变(黑->白或者白->黑)时,其周围上下左右(如果存在的话)的格子的颜色也被反转,问至少反转几个格子可以使4*4的正方形变为纯白或者纯黑?

主要思路如下:

1.对于每个格子,它要么反转0次,要么反转1次(当然,它的邻格子也跟着反转),因为它反转偶数次和反转0次的效果是一样的,同理反转奇数次的效果和反转1次的效果是一样的。

2.由于只有16个格子,我们可以选择0个格子,1个格子,2个格子,3个格子......进行反转,总的选择情况为

3.当0个格子被反转时,看它是否为纯色,否则选择一个格子进行反转(有16种选择),看反转后是否为纯色,否则选择两个格子进行反转(有120种选择),看反转后是否为纯色......
4.只要"3过程"中有纯色出现,就停止"3过程",输出相应的被选择的格子个数,结束。如果16个格子都被翻转了,还是没变成纯色,则输出“Impossible”。

对于从16个格子中选取n个格子的所有组合,请看前一篇文章,这里不再叙述。

整个程序代码如下:

1 /*  2 POJ 1753 Flip Game (递归枚举)  3 By Microgoogle  4 */  5 #include 
6 #include
7 8 //所有都是白的,或者所有都是黑的 9 int all_white_or_black(int* bits, int len) 10 { 11 int i = 0; 12 for (i = 0; i < len - 1; i++) 13 if (bits[i] != bits[i + 1]) 14 return 0; 15 return 1; 16 } 17 18 //改变一个格子的颜色,并根据其所在位置改变其周围格子的颜色 19 void change_color(int* arr, int i) 20 { 21 arr[i] = !(arr[i]); 22 int x = i/4; 23 int y = i%4; 24 if (y < 3) 25 arr[i + 1] = !(arr[i + 1]); 26 if (y > 0) 27 arr[i - 1] = !(arr[i - 1]); 28 if (x > 0) 29 arr[i - 4] = !(arr[i - 4]); 30 if (x < 3) 31 arr[i + 4] = !(arr[i + 4]); 32 } 33 34 //递归判断 35 //这个完全用了前一篇文章的递归方法,只是在else语句中添加了整个图形是否为纯色的判断而已 36 void combine(int* arr, int len, int* result, int count, const int NUM, int* last) 37 { 38 int i; 39 for (i = len; i >= count; i--) 40 { 41 result[count - 1] = i - 1; 42 if (count > 1) 43 combine(arr, i - 1, result, count - 1, NUM, last); 44 else 45 { 46 int j = 0; 47 //在这里生成arr的副本 48 int* new_arr = (int*)malloc(sizeof(int)*16); 49 for (j = 0; j < 16; j++) 50 new_arr[j] = arr[j]; 51 52 for (j = NUM - 1; j >=0; j--) 53 { 54 change_color(new_arr, result[j]); 55 } 56 if (all_white_or_black(new_arr, 16)) 57 { 58 *last = NUM; 59 free(new_arr); 60 break; 61 } 62 free(new_arr); 63 } 64 } 65 } 66 67 int main() 68 { 69 char str[5]; 70 int bits[16]; 71 int count = 15; 72 int lines = 4; 73 while (lines--) 74 { 75 scanf("%s", str); 76 int i; 77 for (i = 0; i < 4; i++) 78 { 79 if (str[i] == 'b') 80 bits[count--] = 1; 81 else 82 bits[count--] = 0; 83 } 84 } 85 86 if (all_white_or_black(bits, 16)) 87 printf("%d\n", 0); 88 else 89 { 90 //生成bits数组的副本 91 int* new_bits = (int*)malloc(sizeof(int)*16); 92 int i; 93 for (i = 0; i < 16; i++) 94 new_bits[i] = bits[i]; 95 96 int j; 97 //这里last用来接受combine函数里面的NUM,即需要的步数 98 int last = 0; 99 for (j = 1; j <= 16; j++)100 {101 int* result = (int*)malloc(sizeof(int)*j);102 combine(new_bits, 16, result, j, j, &last);103 if (last == j)104 {105 printf("%d\n", last);106 break;107 }108 //new_bits已被改变,所以要还原为bits109 for (i = 0; i < 16; i++)110 new_bits[i] = bits[i];111 112 free(result);113 }114 free(new_bits);115 116 if (j == 17)117 printf("Impossible\n");118 }119 120 return 0;121 }

转载地址:http://unxal.baihongyu.com/

你可能感兴趣的文章
深入了解 Linux下安装DNS+Sendmail服务
查看>>
python在类中实现swith case功能
查看>>
Maven com.sun.jdmk:jmxtools:jar 下载不下来
查看>>
DevExpress之Skin自定义使用
查看>>
可变参数
查看>>
[日推荐]『饿了么外卖服务』饿了么官方小程序,无需下载安装!
查看>>
JavaScript 作用域
查看>>
Linux Ubuntu 16.04 主机名设置
查看>>
CCNP 静态路由
查看>>
单链表二[不带头节点链表]
查看>>
Spring mvc 拦截器
查看>>
MySQL GROUP BY 和GROUP_CONCAT的一些用法
查看>>
## mysqldump 导出数据库各参数详细说明
查看>>
java中URL编码和中文相互转换
查看>>
影评:《云图》:生命并非微不足道
查看>>
hibernate4之一对一关系映射(二)
查看>>
我的友情链接
查看>>
Android第五课 编译错误分析
查看>>
VS_远程调试
查看>>
博为峰Java技术题 ——JavaSE Java实现在不同编码之间进行文件转换
查看>>