標籤:
題意:
有一個n*n(n<=1000)的01矩陣
Q次詢問(1000) 每次詢問有幾個大於等於k的全為一的子矩形
從右下角往右上方預先處理
每個點有一個r x v
r代表右邊有多少連續1
x代表下面有多少連續1
v代表以這個為左上方的矩陣最大是多少
所以v[i][j]= min(r[i][j+1], x[i+1][j],v[i+1][j+1]) +1
r[i][j]=r[i][j+1]+1;
x[i][j]=x[i+1][j]+1;
然後ans[v[i][j]]++
預先處理尾碼和 O 1 輸出
#include<cstdio>#include<cstring>#include<string>#include<iostream>#include<algorithm>#include<map>using namespace std;const int N=50005;int n,k,m;int s[1005];int v[1005][1005],r[1005][1005],x[1005][1005],a[1005][1005];char c[1005];int main(){ int i,j; int T; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); memset(s,0,sizeof(s)); memset(r,0,sizeof(r)); memset(x,0,sizeof(x)); for(i=1; i<=n; i++) { scanf("%s",c); for(j=0;j<n;j++) a[i][j+1]=c[j]-‘0‘; } x[n+1][n]=0; r[n][n+1]=0; v[n+1][n+1]=0; for(i=n; i>=1; i--) { for(j=n; j>=1; j--) { if(a[i][j]) { v[i][j]=min(min(v[i+1][j+1],r[i][j+1]),x[i+1][j]); r[i][j]=r[i][j+1]+1; x[i][j]=x[i+1][j]+1; v[i][j]++; } else v[i][j]=r[i][j]=x[i][j]=0; s[v[i][j]]++; } } for(i=n-1; i>=1; i--) { s[i]+=s[i+1]; } while(m--) { scanf("%d",&k); cout<<s[k]<<endl; } } return 0;}
HDU電腦學院大學生程式設計競賽(2015’12)1006 01 Matrix