【POJ-3279】Fliptile(二进制枚举+DFS)

【POJ-3279】Fliptile

题目要求

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 4
1 0 0 1
0 1 1 0
0 1 1 0
1 0 0 1

Sample Output

0 0 0 0
1 0 0 1
1 0 0 1
0 0 0 0

解题思路

一开始我用纯dfs进行搜索,枚举每一个点,毫无疑问,直接TLE,后来考虑,既然我们不能枚举所有操作,那我们不如只枚举一行的操作,然后根据这一行的操作来推出后面每一行的操作,最后判断能不能满足题目要求,即所有的棋子均为白色。

我们怎样推出后面每一行的操作呢?我们从第二行开始,枚举每一行的点,如果这个点正上方的一个点是黑色的,那么为了满足题意,只有将该棋子翻过来,才能使上面的棋子变成白色的。因为这个翻转棋只有两面,如果翻两次的话就相当于没翻,所以我们只需要标记需不需要翻即可。

在枚举操作的时候,因为数量较小,而且每个棋子只有两种情况(翻与不翻),所以使用二进制枚举。

把以上几点考虑到,就可以顺利写出代码了hhh

AC代码

#include
#include
#include
using namespace std;

int Map[20][20],cal[20][20],ans[20][20];
int n,m;
int dir[5][2]={
    {0,0},{1,0},{-1,0},{0,1},{0,-1}};

int getcolor(int x,int y)//根据原图中的颜色以及该点及周围点的反转情况,确定该点此时的颜色。
{
	int ans=Map[x][y];

	for(int i=0;i<5;i++)
	{
		int tx=x+dir[i][0];
		int ty=y+dir[i][1];

		if(tx<0||ty<0||tx>=n||ty>=m)continue;//防止越界
		else ans+=cal[tx][ty];
	}
	return ans%2;
}

int dfs()
{
	for(int i=1;i>n>>m)
	{
		for(int i=0;i>Map[i][j];

		int res=(1<<30)-1;
		for(int i=0;i<1<0;j--)
			{
				int num=m-j;
				int temp=1<<(j-1);
				if(i&temp)
				cal[0][num]=1;
			}

			int now=dfs();
			if(now>=0&&now

你可能感兴趣的:(ACM)