POJ - 3279 Fliptile(点亮所有的灯)

来源:互联网 发布:恋上我的帅和尚知乎 编辑:程序博客网 时间:2024/05/17 01:19

题目:

Description

Farmer John knows that an intellectually satisfied cow is a happy cow who will give more milk. He has arranged a brainy activity for cows in which they manipulate an M × N grid (1 ≤ M ≤ 15; 1 ≤ N ≤ 15) of square tiles, each of which is colored black on one side and white on the other side.

As one would guess, when a single white tile is flipped, it changes to black; when a single black tile is flipped, it changes to white. The cows are rewarded when they flip the tiles so that each tile has the white side face up. However, the cows have rather large hooves and when they try to flip a certain tile, they also flip all the adjacent tiles (tiles that share a full edge with the flipped tile). Since the flips are tiring, the cows want to minimize the number of flips they have to make.

Help the cows determine the minimum number of flips required, and the locations to flip to achieve that minimum. If there are multiple ways to achieve the task with the minimum amount of flips, return the one with the least lexicographical ordering in the output when considered as a string. If the task is impossible, print one line with the word "IMPOSSIBLE".

Input

Line 1: Two space-separated integers: M and N 
Lines 2.. M+1: Line i+1 describes the colors (left to right) of row i of the grid with N space-separated integers which are 1 for black and 0 for white

Output

Lines 1.. M: Each line contains N space-separated integers, each specifying how many times to flip that particular location.

Sample Input

4 41 0 0 10 1 1 00 1 1 01 0 0 1

Sample Output

0 0 0 01 0 0 11 0 0 10 0 0 0

这是一个叫做点亮所有的灯的游戏:点亮所有的灯(这里面有这个游戏的链接,可以玩玩,很好玩)

这个题目的意思是输入m,n,输入m*n的0-1矩阵,要求输出1个m*n的0-1矩阵。

具体的要求是,输入的游戏局面,要求给出一个点亮所有的灯的方案。

比如:


这个局面就是:

0 0 1 1 0 

1 0 1 0 1

1 1 0 0 0 

1 0 0 1 0 

1 1 0 1 0

输出的是,需要点击的格子即为1,不需要点击的即为0,每个格子最多点1次,不需要更多。

这所有的一切,都和上面提到的点亮所有的灯这篇博客里面一模一样,那里有详细的叙述。

在那篇文章中,有详细的思路,这里不再重复。

总之,输出的矩阵完全由第一行确定。

题目的意思是,如果有多个可行的方案的话,输出字典序最小的方案。

但是标程里面的字典序有问题,详情:点击打开链接


因为点亮所有的灯这篇博客是针对我自己玩游戏的情况,而这里是针对ACM编程,

所以,虽然是同样的问题,但是代码略有区别。

在这里,我用到了状态压缩,即用1个整数表示1行。

不过这样写出来的代码确实很难看懂,应用点亮所有的灯这篇博客里面的术语来说:

f(k)表示的是,一个k代表的行操作对应的行增量,即对某一行进行k代表的行操作,那么这一行会有什么影响。

比如说,如果k代表的是a b c d e,那么对应的影响就是a+b    a+b+c    b+c+d    c+d+e    d+e

这个影响,可以看成3个影响的叠加:(1)a b c d e(2)b c d e 0(3)0 a b c d

状态压缩之后就是f里面的计算方法了。

代码:

#include<iostream>using namespace std;int m, n, a;int l[17];int temp[17];int f(int k){int t = (1 << n) - 1;return (k * 2 ^ k^k / 2)&t;}bool ok(int k){for (int i = 0; i < 17; i++)temp[i] = l[i];temp[0] = k;for (int i = 1; i < m; i++){temp[i] = (temp[i] ^ f(temp[i - 1]));temp[i + 1] = (temp[i + 1] ^ temp[i - 1]);}return temp[m]==f(temp[m-1]);}void out(int k){for (int i = 0; i < 17; i++)temp[i] = l[i];temp[0] = k;for (int i = 1; i <= m; i++){for (int j = 0; j < n; j++){cout << (temp[i - 1] >> j) % 2;if (j < n - 1)cout << " ";}cout << endl;temp[i] = (temp[i] ^ f(temp[i - 1]));temp[i + 1] = (temp[i + 1] ^ temp[i - 1]);}}int main(){cin >> m >> n;for (int i = 0; i < 17; i++)l[i] = 0;for (int i = 1; i <= m; i++)for (int j = 0; j < n; j++){cin >> a;l[i] += (a << j);}for (int k = 0; k < (1 << n); k++)if (ok(k)){out(k);return 0;}cout << "IMPOSSIBLE" << endl;return 0;}

1 0
原创粉丝点击