poj1753

http://www.cnblogs.com/shuaiwhu/archive/2012/04/27/2474041.html

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

malloc函数用法

https://blog.csdn.net/linan5231/article/details/50930630

1、函数声明
void *malloc(int size);

说明:malloc向系统申请分配size字节的内存空间,返回类型为void*类型。

2、使用
int *p;

p = (int *)malloc( sizeof(int) );

注意:

(1)因为malloc返回的是不确定类型的指针,所以返回之前必须经过类型强制转换,否则编译报错,如:“ 不能将void*赋值给int*变量 ”。

(2)malloc只管分配内存,并不会初始化,其内存空间中的值可能是随机的。如果分配的这块空间原来没有被使用过,那么其中每个值都可能是0。相反,空间里面可能遗留各种各样的值。

(3)实参为需要分配的字节大小,如果malloc(1),那么系统只分配了1个字节的内存空间,这时注意,如果在这块空间中存放一个int值,由于int类型占4个字节,那么还有3个字节未分配空间,系统就会在已经分配的那1个字节的基础上,依次向后分配3个字节空间,而这就占有了“别人”的3个字节空间,“别人”原有的值就被清空了。

(4)分配的空间不再使用时,要用free函数释放这块内存空间。

3、示例
分配100个int类型的空间:

int *p;

p = (int *)malloc( sizeof(int) * 100 );

原文地址:https://www.cnblogs.com/fengzhongzhuifeng/p/10711859.html