1. 程式人生 > >Luogu P2733 家的範圍 Home on the Range

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; }