牛客小白月赛4 20180616C

题目描述

铁子和顺溜上生物课的时候不小心将几滴超级病菌滴到了培养皿上,这可急坏了他们。
培养皿可以被看成一个n*n的方格,最初病菌滴在了这n*n的格子中的某些格子,病菌的传染方式是这样的,如果一个方格与两个或多个被感染的方格相邻(两个方格相邻当且仅当它们只有一条公共边),那么它就会被感染。现在铁子和顺溜想知道,最终所有的方格会不会都被感染。
输入描述:
第一行两个整数n,m。n表示方格的规格,m表示最初病菌所在的格子数。(1≤n ≤1000, 0 < m < n)。接下来m行每行两个整数xi,yi表示第xi行的第yi个格子有病菌。数据保证不会有两个病菌初始时在同一个格子。
输出描述:
如果最终所有的方格都会被感染,输出 YES。
否则输出 NO。

分析

骗分大法好,因为n≤1000,数据范围略小,所以考略暴力骗分,可根据打表得当m<n/3时,一定是不行的,所以m<n/3直接输出NO;接着是m<n/3,这时可按照时间一遍一遍的模拟,若在一轮中没有新的出现,则break,此时在扫过整个部分,若有未感染输出NO,直接return 0;最后在输出YES,时间:9ms。
上代码

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int al[1002][1002],n,m,k,x,y;
int main(){
    memset(al,0,sizeof(al));
    scanf("%d%d",&n,&m);
    if(m<n/3){
        printf("NO\n");
        return 0;
    }
    for(int i=1;i<=m;i++)scanf("%d%d",&x,&y);
    while(1){
        k=0;
        for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) if(!al[i][j]){
            if(al[i-1][j]+al[i+1][j]+al[i][j-1]+al[i][j+1]>=2)al[i][j]=1,k=1;
        }
        if(!k) break;
    }
    k=0;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            if(!al[i][j]){
                k=1;
                break;
            }
        }
        if(k==1) break;
    }
    if(!k) printf("YES\n");
    else printf("NO\n");
    return 0;
}

猜你喜欢

转载自blog.csdn.net/sjzezwzy/article/details/80715302