Baby Ming and Binary image
Time Limit: 2000/1000 MS (Java/Others)
Memory Limit: 65536/65536 K (Java/Others)
问题描述
铭宝宝很喜欢像素图,所以,他喜欢把像素图都做如下的处理: 首先,把像素图变换成二值图(用01表示),然后,在二值图中,把每个点以及和它相邻的点(最多9个点)的01值加起来,并保存在一个矩阵Mat中。 铭宝宝选择的图像底边和顶边都是空白的(二值图中值为0),因为他觉得这样的图很漂亮。 不过因为矩阵很大,铭宝宝担心记录过程中出错。所以现在铭宝宝想知道,根据他所保存下来的矩阵Mat,是否能还原出二值图。
输入描述
输入T表示测试组数(T≤30) 输入两个数n,m表示二值图的大小(即矩阵M的大小) (2<n≤12,m≤100) 接下来输入n行,每行m个数,表示矩阵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;
}