Luogu P2733 家的范围 Home on the Range

题意:

  给你一个01方阵,求不同大小的全1方阵的个数

思路:

  对每个点,判断以它左上角的点的方阵是否为全1方阵,若有n*n的全1方阵,则(n-1)^2的方阵必为全1,所以要判断n^2是否为全1方阵,前提是(n-1)^2是全1方阵。n^2全1方阵的判断方法((n-1)^2已判断为全1方阵):判断方阵最下行和最右列是否为全1,对每行算前缀和,每列算前缀和。若方阵最下行和最右列的数相加==2*n,则为n^2的全1方阵。

#include<iostream>
#include<vector> 
#include<queue>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<map>
#define INF 0x7f7f7f7f
#define MAX_INT 0x7fffffff
#define pi 3.1415926
typedef unsigned int uint;
using namespace std;
typedef long long LL; 
int mc[252][252];
int rad[252][252];
int cad[252][252]; 
int cnt[251];
int main(){
    memset(cnt,0,sizeof(cnt));
    memset(rad,0,sizeof(rad));
    memset(cad,0,sizeof(cad));
    int n;char c;
    cin>>n;
    for(int i=0;i<n;i++)
    for(int j=0;j<n;j++){
        cin>>c; 
        mc[i][j]=c-'0';
    }
    for(int i=0;i<n;i++){
        rad[i][0]=mc[i][0];
        for(int j=1;j<n;j++)
            rad[i][j]=rad[i][j-1]+mc[i][j]; 
    }
    for(int i=0;i<n;i++){
        cad[0][i]=mc[0][i];
        for(int j=1;j<n;j++)
            cad[j][i]=cad[j-1][i]+mc[j][i]; 
    }    
    int rc,cc;
    for(int i=0;i<n;i++)
    for(int j=0;j<n;j++)
    for(int s=1;;s++){
        rc=cc=0;
        if(j==0) rc=rad[i+s-1][j+s-1];
        else rc=rad[i+s-1][j+s-1]-rad[i+s-1][j-1];
        if(i==0) cc=cad[i+s-1][j+s-1];
        else cc=cad[i+s-1][j+s-1]-cad[i-1][j+s-1];
        if(cc+rc==2*s){
            cnt[s]++;
        } 
        else break;
    } 
    for(int i=2;i<=n;i++)
    if(cnt[i]) cout<<i<<' '<<cnt[i]<<endl;
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/Gsimt/p/10035151.html