poj1753解题报告(枚举、组合数)

来源:互联网 发布:彩虹六号 知乎 编辑:程序博客网 时间:2024/05/21 08:55

 

POJ 1753,题目链接http://poj.org/problem?id=1753

题意:

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

 

思路:

1. 每一个位置只有两种颜色,翻偶数次等于没有翻,所以只有翻基数次对棋盘有影响,即只用考虑一个位置最多翻一次。

2. 一共有16个位置,所以最多翻16次。那么可能翻0次就成功、或者翻1次成功、或者翻2次成功...或者翻16次成功。

3. 每个位置翻转的顺序对结果无影响。

那么这就变成了一个组合数问题:

将输入的16个元素放到一个数组中,进行组合数计算即可。(组合数+枚举)

 

代码1

/** Memory: 384K* Time: 16MS*/#include <cstdio>#include <cstdlib>#define ALLNUM 16static int count = 0;/** 15 14 13 12* 11 10  9  8*  7  6  5  4*  3  2  1  0*/void flip(int& data, int posIdx){data ^= 1<<posIdx;//upif (posIdx < 12) data ^= 1<<(posIdx+4);//downif (posIdx > 3)  data ^= 1<<(posIdx-4);//leftif (posIdx%4+1 != 4) data ^= 1<<(posIdx+1);//rightif (posIdx%4 != 0) data ^= 1<<(posIdx-1);}bool isOK(int data){if (data == 0 || data == 0xffff) return true;else return false;}/** num 1 -- ALLNUM* starIdx 0 -- ALLNUM-1*/void func(int num, int starIdx, int data, int step){//printf("-----------comein >> starIdx=%d, num=%d\n", starIdx, num);if (num == 1){++step;for (int i=starIdx; i<ALLNUM; ++i){int temp = data;flip(temp, i);if (isOK(temp)) {printf("%d\n", step);exit(0);}//log++count;}}else if (starIdx+num <= ALLNUM){ // 14 + 2 <= 16  (14 15) ++step;for (int i=starIdx; i<=ALLNUM-num; ++i){int temp = data;flip(temp, i);func(num-1, i+1, temp, step);}}// else {// printf("Error Branch----------- >> starIdx=%d, num=%d\n", starIdx, num);// }}// black 0, white 1int main(){int num = ALLNUM;int data = 0;char c;while (true){scanf("%c", &c);if (c == '\n') continue;--num;if (c == 'w') data ^= 1<<num;if (num == 0)  break;}if (isOK(data)) {printf("0\n");return 0;}for (int i=1; i<=ALLNUM; ++i){func(i, 0, data, 0);//printf("i=%d,AllCount=%d\n", i, count);}printf("Impossible\n");return 0;}

 

代码2

//356K 313MS#include <cstdio>#include <cstdlib>#define ALLNUM 16bool isOK(int data){if (data == 0 || data == 0xffff) return true;else return false;}void flip(int& data, int posIdx){data ^= 1<<posIdx;//upif (posIdx < 12) data ^= 1<<(posIdx+4);//downif (posIdx > 3)  data ^= 1<<(posIdx-4);//leftif (posIdx%4+1 != 4) data ^= 1<<(posIdx+1);//rightif (posIdx%4 != 0) data ^= 1<<(posIdx-1);}// black 0, white 1int main(){int num = ALLNUM;int data = 0;char c;while (true){scanf("%c", &c);if (c == '\n') continue;--num;if (c == 'w') data ^= 1<<num;if (num == 0)  break;}int step = ALLNUM;bool bImpossible = true;for (int i=0; i<=0xffff; ++i){int tempData = data;int tempStep = 0;for (int idx=0; idx<ALLNUM; ++idx){if ((1<<idx) & i){ //idx位置需要翻转flip(tempData, idx);++tempStep;}}if (isOK(tempData) && tempStep < step) step = tempStep;}if (step == ALLNUM)printf("Impossible\n");else printf("%d\n", step);return 0;}

 

 

 

 

 

 

0 0
原创粉丝点击