POJ 1753 Flip Game (递归枚举)

转载http://www.cnblogs.com/shuaiwhu/archive/2012/04/27/2474041.html  作者:Microgoogle


POJ 1753,题目链接http://poj.org/problem?id=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”。


/*
 POJ 1753 Flip Game (递归枚举)
 By Microgoogle
 */
 #include <stdio.h>
 #include <stdlib.h>
 
 //所有都是白的,或者所有都是黑的
 int all_white_or_black(int* bits, int len)
 {
   int i = 0;
   for (i = 0; i < len - 1; i++)
     if (bits[i] != bits[i + 1])
       return 0;
   return 1;
 }
 
 //改变一个格子的颜色,并根据其所在位置改变其周围格子的颜色
 void change_color(int* arr, int i)
 {
   arr[i] = !(arr[i]);
   int x = i/4;
   int y = i%4;
   if (y < 3)
     arr[i + 1] = !(arr[i + 1]);
   if (y > 0)
     arr[i - 1] = !(arr[i - 1]);
   if (x > 0)
     arr[i - 4] = !(arr[i - 4]);
   if (x < 3)
     arr[i + 4] = !(arr[i + 4]);
 }
 
 //递归判断
 //这个完全用了前一篇文章的递归方法,只是在else语句中添加了整个图形是否为纯色的判断而已
 void combine(int* arr, int len, int* result, int count, const int NUM, int* last)
 {
   int i;
   for (i = len; i >= count; i--)
   {
     result[count - 1] = i - 1;
     if (count > 1)
       combine(arr, i - 1, result, count - 1, NUM, last);
     else
     {
       int j = 0;
       //在这里生成arr的副本
       int* new_arr = (int*)malloc(sizeof(int)*16);
       for (j = 0; j < 16; j++)
         new_arr[j] = arr[j];
 
       for (j = NUM - 1; j >=0; j--)
       {
          change_color(new_arr, result[j]);
       }
       if (all_white_or_black(new_arr, 16))
       {
          *last = NUM;
          free(new_arr);
          break;
       }
       free(new_arr);
     }
   }
 }
 
 int main()
 {
   char str[5];
   int bits[16];
   int count = 15;
   int lines = 4;
   while (lines--)
   {
     scanf("%s", str);
     int i;
     for (i = 0; i < 4; i++)
     {
       if (str[i] == 'b')
         bits[count--] = 1;
       else
         bits[count--] = 0;
     }
   }
 
   if (all_white_or_black(bits, 16))
     printf("%d\n", 0);
   else
   {
     //生成bits数组的副本
//     int* new_bits = (int*)malloc(sizeof(int)*16);
//     int i;
//     for (i = 0; i < 16; i++)
//       new_bits[i] = bits[i];
 
     int j;
     //这里last用来接受combine函数里面的NUM,即需要的步数
     int last = 0;
     for (j = 1; j <= 16; j++)
     {
       int* result = (int*)malloc(sizeof(int)*j);
//       combine(new_bits, 16, result, j, j, &last);
       combine(bits, 16, result, j, j, &last);
       if (last == j)
       {
         printf("%d\n", last);
         break;
       }
       //new_bits已被改变,所以要还原为bits
//       for (i = 0; i < 16; i++)
//         new_bits[i] = bits[i];
      
       free(result);
     }
//     free(new_bits);
 
     if (j == 17)
       printf("Impossible\n");
   }
  
   return 0;
 }


基于bert实现关系三元组抽取python源码+数据集+项目说明.zip基于bert实现关系三元组抽取python源码+数据集+项目说明.zip基于bert实现关系三元组抽取python源码+数据集+项目说明.zip基于bert实现关系三元组抽取python源码+数据集+项目说明.zip基于bert实现关系三元组抽取python源码+数据集+项目说明.zip 个人大四的毕业设计、课程设计、作业、经导师指导并认可通过的高分设计项目,评审平均分达96.5分。主要针对计算机相关专业的正在做毕设的学生和需要项目实战练习的学习者,也可作为课程设计、期末大作业。 [资源说明] 不懂运行,下载完可以私聊问,可远程教学 该资源内项目源码是个人的毕设或者课设、作业,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96.5分,放心下载使用! 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),供学习参考。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值