Forgery CodeForces

一道印章刻印的题目;

具体要求:有一个固定的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 }
原文地址:https://www.cnblogs.com/chen-tian-yuan/p/10539309.html