• POJ 1753 Flip Game (递归枚举)


    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”。


    对于从16个格子中选取n个格子的所有组合,请看前一篇文章从数组中取出n个元素的所有组合(递归实现),这里不再叙述。

    整个程序代码如下:

      1 /*
      2 POJ 1753 Flip Game (递归枚举)
      3 By Microgoogle
      4 */
      5 #include <stdio.h>
      6 #include <stdlib.h>
      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已被改变,所以要还原为bits
    109       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 }
  • 相关阅读:
    C语言移动一个点
    C语言数据结构无向图
    C语言学生管理系统(C语言课程设计/精简版)
    C语言贪吃蛇
    2017蓝桥杯九宫幻方(C++B组)
    2017蓝桥杯Excel地址(C++C组)
    2017蓝桥杯杨辉三角(C++C组)
    2017蓝桥杯算式900(C++C组)
    2017蓝桥杯兴趣小组(C++C组)
    javascript 的默认对象
  • 原文地址:https://www.cnblogs.com/null00/p/2474041.html
Copyright © 2020-2023  润新知