题目链接: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; }