二染色问题

一个N*N的网格,初始为白色。现在有一个K*K的印章,每次操作:你可以用印章把网格中一个K*K的子矩形染成黑色或白色。如果一个格子被多次染色,那么后一次染色会覆盖掉前一次的。现在,给你N*N的由黑白两色构成的图案board(board[i][j]为第i行第j列格子的颜色,不是白字母‘W’表示,就是黑由字母‘B’表示),问是否能通过若干次操作,将网格从初始状态染成图案board的样子。如果可以输出"Possible",否则输出"Impossible".
Input
多组测试数据,第一行一个整数T,表示测试数据数量,1<=T<=5
每组测试数据有相同的结构构成:
每组数据一行两个整数N与K,其中1<=K<=N<=20。
之后N行,每行N个字符,表示board,字符都由‘W’与‘B’构成。
Output
每组数据一行输出,即是否可能染出board图案来。
Input示例
3
4 3
BBBW
BWWW
BWWW
WWWW
2 2
BW
WB
6 2
BWBWBB
WBWBBB
BWBWBB
WBWBBB
BBBBBB
BBBBBB
Output示例
Possible
Impossible
Possible
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;

const int MAXN = 25;

char input[MAXN][MAXN];
bool vis[MAXN][MAXN];
int t, n, k;

int main()
{
	cin >> t;

	int sumA, sumB;
	while (t--)
	{
		cin >> n >> k;
		memset(vis, 0, sizeof(vis));

		bool flag = true;
		for (int i = 0; i < n; i++)
		{
			cin >> input[i];
		}

		while (flag)
		{
			flag = false;
			for (int i = 0; i <= n - k; i++)
			{
				for (int j = 0; j <= n - k; j++)
				{
					sumA = 0;
					sumB = 0;
					bool found = false;
					for (int l = i; l < i + k; l++)
					{
						for (int r = j; r < j + k; r++)
						{
							if (vis[l][r])
							{
								continue;
							}
							found = true;
							if (input[l][r] == 'B')
							{
								sumA++;
							}
							else
							{
								sumB++;
							}
						}
					}

					if ((sumA == 0 || sumB == 0) && found)
					{
						flag = true;
						for (int l = i; l < i + k; l++)
						{
							for (int r = j; r < j + k; r++)
							{
								vis[l][r] = true;
							}
						}
					}
				}
			}
		}

		flag = true;

		for (int i = 0; i < n; i++)
		{
			for (int j = 0; j < n; j++)
			{
				if (!vis[i][j] && input[i][j] == 'B')
				{
					flag = false;
				}
			}
		}

		if (flag)
		{
			cout << "Possible" << endl;
		}
		else
		{
			cout << "Impossible" << endl;
		}
	}

    return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值