真心觉得昨晚写这个的时候就是个傻子,硬写最后还fst19了。
昨晚想到的方法对于每一个#,如果这个是一个符合条件的图,那么这个#就一定会包含在一个3X3的环内,那么这个#就有8种可能的位置,挨个去搜看有没有一个可能的位置就好。还是挺难写的这样。
刚刚又想了下,每一个环,都一定会有一个中心,那么我们枚举每一个点,检测它是不是这样一个环的中心,如果是,那么久将它周围的这个环上的点都标记,那么最后扫一遍整个矩阵,看是否还有是#的点但是没有被标记的,如果有,那么这个就是不合法的,反之合法。这个就好写多了,还挺简单。。。感觉自己真的智熄。
代码如下:
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
int gcd(int a,int b){if (b == 0) return a; return gcd(b , a%b);}
int lcm(int a, int b){ return a/gcd(a,b)*b;}
inline int read(){
int f = 1, x = 0;char ch = getchar();
while (ch > '9' || ch < '0'){if (ch == '-')f = -f;ch = getchar();}
while (ch >= '0' && ch <= '9'){x = x * 10 + ch - '0';ch = getchar();}
return x * f;
}
const int maxn = 1e3 + 10;
char s[maxn][maxn];
int vis[maxn][maxn];
void check(int x,int y){
int tag = 0;
for (int i=-1; i<=1; i++) {
for (int j=-1; j<=1; j++) {
if (i != 0 || j != 0){
if (s[x+i][y+j] == '#'){
tag++;
}
}
}
}
if (tag == 8){
for (int i=-1; i<=1; i++) {
for (int j=-1; j<=1; j++) {
if (i != 0 || j != 0){
vis[x+i][y+j] = 1;
}
}
}
}
}
int main(){
int n = read(),m = read();
for (int i=1; i<=n; i++) {
scanf("%s",s[i]+1);
}
for (int i=2; i<n; i++) {
for (int j=2; j<m; j++) {
check(i, j);
}
}
for (int i=1; i<=n; i++) {
for (int j=1; j<=m; j++) {
if (s[i][j] == '#' && vis[i][j] == 0){
cout << "NO" << endl;
return 0;
}
}
}
cout << "YES" << endl;
return 0;
}