zoukankan      html  css  js  c++  java
  • 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 );

  • 相关阅读:
    HDU 1063 Exponentiation
    HDU 1261 字串数
    HDU 1715 大菲波数
    HDU 1002 A + B Problem II
    csharp 復制DataTable修改某列的值
    解决IE6下透明PNG图片有灰底的解决方案
    webform TextBox以一条横线显示 兼容各主流瀏覽器 .
    SQL 工齡計算
    csharp Format CultureInfo
    Csharp Winform TextBox 樣式以一條橫線顯示
  • 原文地址:https://www.cnblogs.com/fengzhongzhuifeng/p/10711859.html
Copyright © 2011-2022 走看看