HDU 5613:Baby Ming and Binary image

45 篇文章 0 订阅

Baby Ming and Binary image

 
 Time Limit: 2000/1000 MS (Java/Others)
 
 Memory Limit: 65536/65536 K (Java/Others)
问题描述
铭宝宝很喜欢像素图,所以,他喜欢把像素图都做如下的处理:
首先,把像素图变换成二值图(用0101表示),然后,在二值图中,把每个点以及和它相邻的点(最多99个点)的0101值加起来,并保存在一个矩阵Mat中。
铭宝宝选择的图像底边和顶边都是空白的(二值图中值为00),因为他觉得这样的图很漂亮。
不过因为矩阵很大,铭宝宝担心记录过程中出错。所以现在铭宝宝想知道,根据他所保存下来的矩阵Mat,是否能还原出二值图。

输入描述
输入TT表示测试组数(T \leq 30)(T30)
输入两个数n, mn,m表示二值图的大小(即矩阵M的大小) (2 < n \leq 12, m \leq 100)(2<n12,m100)
接下来输入nn行,每行mm个数,表示矩阵Mar
输出描述
输出Impossible,如果不能还原出二值图
输出Multiple,如果还原出来的二值图不唯一
否则输出二值图
输入样例
2
4 4
1 2 3 2
2 3 4 2
2 3 4 2
1 1 1 0
3 1
1
1
0
输出样例
0 0 0 0
0 1 1 1
0 1 0 0
0 0 0 0
Impossible
Hint
样例2中,因为[1 0 0]不是铭宝宝选择的矩阵,所以无解

很好玩的一道题,之前没有接触过这种题目。因为发现n比较小,所以可以枚举第一列的状态,然后如果第一列的状态是确定的话,那么根据矩阵中的数是可以不断递推出右下角的值的。

判断的地方还挺多的,一些细节需要注意一下就可以了。

代码:

#pragma warning(disable:4996)
#include <iostream>  
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>  
#include <string>  
#include <cmath>
#include <queue>
#include <map>
using namespace std;

typedef long long ll;
const int maxn = 5005;

int n, m;
int val[15][105], enu[15][105], res_matrix[15][105];

void input()
{
	int i, j;
	scanf("%d%d", &n, &m);

	for (i = 1; i <= n; i++)
	{
		for (j = 1; j <= m; j++)
		{
			scanf("%d", &val[i][j]);
		}
	}
}

void change(int x)
{
	int i;
	for (i = 1; i <= n; i++)
	{
		enu[i][1] = (x & 1);
		x = x >> 1;
	}
}

bool check()
{
	int i, j;
	for (i = 1; i <= m; i++)
	{
		if (i == 1)
		{
			if (enu[1][i] || enu[n][i])
			{
				return false;
			}
		}
		for (j = 1; j <= n; j++)
		{
			if (j == 1)
			{
				int vv = val[j][i] - (enu[j + 1][i - 1] + enu[j + 1][i]);
				if (vv < 0 || vv>1)
				{
					return false;
				}
				else
				{
					enu[j + 1][i + 1] = vv;
				}
			}
			else if (j == n - 1)
			{
				int vv = val[j][i] - (enu[j][i] + enu[j][i - 1] + enu[j][i + 1] + enu[j - 1][i] + enu[j - 1][i - 1] + enu[j - 1][i + 1]);
				if (vv != 0)
				{
					return false;
				}
				else
				{
					enu[j + 1][i + 1] = vv;
				}
			}
			else if (j == n)
			{
				int vv = val[j][i] - (enu[j - 1][i] + enu[j - 1][i - 1] + enu[j - 1][i + 1]);
				if (vv != 0)
				{
					return false;
				}
			}
			else
			{
				int vv = val[j][i] - (enu[j - 1][i] + enu[j - 1][i - 1] + enu[j - 1][i + 1] +
					enu[j][i] + enu[j][i - 1] + enu[j][i + 1] + enu[j + 1][i - 1] + enu[j + 1][i]);
				if (vv < 0 || vv>1)
				{
					return false;
				}
				else
				{
					enu[j + 1][i + 1] = vv;
				}
			}

		}
	}
	
	for (i = 1; i <= n; i++)
	{
		if (enu[i][m + 1])
		{
			return false;
		}
	}
	return true;
}

void solve()
{
	int i, res = 0;
	for (i = 0; i <= ((1 << n) - 1); i++)
	{
		memset(enu, 0, sizeof(enu));
		change(i);
		if (check())
		{
			res++;
			for (int k1 = 1; k1 <= n; k1++)
			{
				for (int k2 = 1; k2 <= m; k2++)
				{
					res_matrix[k1][k2] = enu[k1][k2];
				}
			}
		}
	}
	if (res == 0)
	{
		puts("Impossible");
	}
	else if (res > 1)
	{
		puts("Multiple");
	}
	else
	{
		for (int k1 = 1; k1 <= n; k1++)
		{
			for (int k2 = 1; k2 <= m; k2++)
			{
				if (k2 == m)
				{
					printf("%d", res_matrix[k1][k2]);
				}
				else
				{
					printf("%d ", res_matrix[k1][k2]);
				}
			}
			printf("\n");
		}
	}
}

int main()
{
	//freopen("i.txt", "r", stdin);
	//freopen("o.txt", "w", stdout);

	int t;
	scanf("%d", &t);
	while (t--)
	{
		input();
		solve();
	}

	return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值