POJ-1753 翻转技巧

题目大意:给定一个4*4矩阵,要么为白色要么为黑色,求按规则将其翻转为同一颜色的最少翻转次数(这里包括全为白色或者全为黑色)

分析:此题与POJ3279基本没啥区别,分析详见POJ3279解析:点击打开链接

附上代码:

#include<iostream>
using namespace std;
#define min(A,B) A<B?A:B
#define INF 0x3f3f3f3f
int a[6][6];
int b[6][6];
int d[5][2] = { { -1, 0 }, { 1, 0 }, { 0, 0 }, { 0, -1 }, { 0, 1 } };
int ans = INF;
bool getcolor(int x, int y)    //返回x,y的颜色值
{
	int res = a[x][y];
	for (int i = 0; i < 5; i++)
	{
		int fx = x + d[i][0], fy = y + d[i][1];
		if (fx >= 1 && fx <= 4 && fy >= 1 && fy <= 4) res += b[fx][fy];
	}
	return res % 2;
}
int solve()
{
	int res = 0;
	for (int i = 2; i <= 4; i++)       //从第二行开始枚举是否需要翻转
		for (int j = 1; j <= 4; j++)
			if (getcolor(i - 1, j)) b[i][j] = 1;
	for (int i = 1; i <= 4; i++)    //判断最后一行是否满足条件
		if (getcolor(4, i)) return INF;
	for (int i = 1; i <= 4; i++)        //求总翻转次数
		for (int j = 1; j <= 4; j++)
			res += b[i][j];
	return res;
}
int main()
{
	for (int i = 1; i <= 4; i++)
		for (int j = 1; j <= 4; j++)
		{
			char ch;
			cin >> ch;
			if (ch == 'w') a[i][j] = 0;
			else a[i][j] = 1;
		}
	for (int i = 2; i--;)
	{
		if (!i)    //全翻转为白色或者全翻转为黑色都需枚举一次
		{
			for (int i = 1; i <= 4; i++)
				for (int j = 1; j <= 4; j++)
					a[i][j] = (a[i][j] + 1) % 2;
		}
		for (int s = 0; s < 1 << 4; s++)   //枚举第一行有哪些翻转的情况
		{
			memset(b, false, sizeof b);
			for (int i = 1; i <= 4; i++)
				b[1][i] = s >> (4 - i) & 1;
			int t = solve();
			ans = min(ans, t);
		}
	}
	if (ans == INF) printf("Impossible\n");
	else printf("%d\n", ans);
	return 0;
}


你可能感兴趣的:(ACM,题解报告,翻转问题)