Codeforces Round #514 (Div. 2), problem: (B) Forgery

真心觉得昨晚写这个的时候就是个傻子,硬写最后还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;
}

猜你喜欢

转载自blog.csdn.net/CCCCTong/article/details/82950521