一道印章刻印的题目;
具体要求:有一个固定的3*3的印章,给你一个墨迹问能用这个印章印出墨迹吗?(一个像素可以多次被上色)
输入:第一行是墨迹的行列规模,接下来是墨迹
输出:If Andrey can forge the signature, output "YES". Otherwise output "NO".
印章长这样 :
1. 规模不算特别大,保险起见我用的是scanf读入数据,最后AC后测试发现TIME影响不大。(毕竟思路比较耗时,还是喜欢scanf)
2.思路分析:怎样的'#'才是可以被印上的,这是个关键;
3.细节实现:对所有的印章位置预先遍历一下,这里(ok函数里)要判断你传入函数的一个印章是可以被印的吗?如果在周围的8个位置上出现了'.',那么这是一个非法的位置,直接结束;
如果这是合法的位置用数组v的index来记录周围8个位置(bool值为1)
最后在遍历匹配一下就OK了。
1 #include<cstdio> 2 using namespace std; 3 const int max_size = 1000 + 2; 4 char s[max_size][max_size]; 5 bool v[max_size][max_size]; 6 int n, m;//m行n列 7 bool ok(int x,int y) 8 { 9 for(int i=x;i<=x+2;i++) 10 for (int j = y; j <= y + 2; j++) 11 { 12 if (i == x + 1 && j == y + 1)continue; 13 else if (s[i][j] == '.') return false; 14 } 15 for (int i = x; i <= x + 2; i++) 16 for (int j = y; j <= y + 2; j++) 17 { 18 if (i == x + 1 && j == y + 1)continue; 19 else v[i][j] = 1; 20 } 21 return true; 22 } 23 int main() 24 { 25 memset(v, 0, sizeof(v)); 26 scanf("%d%d", &m, &n); 27 for (int i = 1; i <= m; i++) scanf("%s", s[i] + 1); 28 for (int i = 1; i <= m - 2; i++) 29 for (int j = 1; j <= n - 2; j++) 30 ok(i, j);//以(i,j)为起点的一次印 31 bool ans = 1; 32 for (int i = 1; i <= m; i++) 33 { 34 for (int j = 1; j <= n; j++) 35 { 36 if (s[i][j] == '#' && !v[i][j]) { ans = 0; break; } 37 //如果当前位置有墨印,但不可能被染色 38 } 39 if (!ans) break; 40 } 41 if (ans)printf("YES "); 42 else printf("NO "); 43 return 0; 44 }