题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1046
抄答案。
枚举每一个符号,先判断能否只用一个像素来标记,不能的话判断能否用两个像素标记。只要有一个符号不能用一个或两个像素标记时就impossible。
判断一个符号能否用一个(或两个)像素标记时,枚举这个符号中的每一个(或两个)像素,看其他符号的相同位置是否也是像素,当其他所有符号的相同位置都不是像素时(判断两个像素时只要这两个位置有一个不是像素就可以了),该符号才能用一个(或两个)像素来标记。
#include<iostream>
#include<cstdio>
using namespace std;
const int maxCols = 79;
int symbols;
int rows;
int cols;
char pictrue[10][maxCols + 1];
bool notDot(int g, int r, int c)
{
int k = g * (cols + 1) + c;
if (pictrue[r][k] != '.')
return true;
else
return false;
}
bool match1(int g, int r, int c)
{
for (int h=0; h<symbols; h++)
if (h != g && notDot(h,r,c))
return false;
return true;
}
bool match2(int g, int r, int c, int r2, int c2)
{
for (int h=0; h<symbols; h++)
if (h != g && notDot(h,r,c) && notDot(h,r2,c2))
return false;
return true;
}
bool solve(int g)
{
for (int r=0; r<rows; r++)
for (int c=0; c<cols; c++)
{
if (notDot(g,r,c) && match1(g,r,c))
{
int k = g * (cols + 1) + c;
pictrue[r][k] = '#';
return true;
}
}
for (int r=0; r<rows; r++)
for(int c=0; c<cols; c++)
{
if (notDot(g,r,c))
{
for (int c2=c+1; c2<cols; c2++)
if (notDot(g,r,c2) && match2(g,r,c,r,c2))
{
int k = g * (cols + 1) + c;
pictrue[r][k] = '#';
k = g * (cols + 1) + c2;
pictrue[r][k] = '#';
return true;
}
for (int r2=r+1; r2<rows; r2++)
for (int c2=0; c2<cols; c2++)
if (notDot(g,r2,c2) && match2(g,r,c,r2,c2))
{
int k = g * (cols + 1) + c;
pictrue[r][k] = '#';
k = g * (cols + 1) + c2;
pictrue[r2][k] = '#';
return true;
}
}
}
return false;
}
int main()
{
int test = 1;
while (cin>>symbols>>rows>>cols)
{
if (symbols == 0)
break;
getchar();
for (int r=0; r<rows; r++)
gets(pictrue[r]);
printf("Test %d\n",test++);
bool impossible = false;
for (int g=0; !impossible && g<symbols; g++)
if (!solve(g))
impossible = true;
if (impossible)
cout<<"impossible"<<endl;
else
for (int r=0; r<rows; r++)
cout<<pictrue[r]<<endl;
}
return 0;
}