题意:给你一个矩形,问你从左上角 到右下角有多少个全部为0的矩形
思路:看了题解才发现真的是学到了,矩形的个数可以通过查行数(指定区域内的行数)每行的0的长度相加就的得到包含右下角的矩形个数,前面是一个基础的容斥,还有就是%1d,这个真的是学到的,还可以这样输入数字(大佬们就是强)
代码:
#include <bits/stdc++.h> using namespace std; const int maxn=45; int a[maxn][maxn],row[maxn][maxn],dp[maxn][maxn][maxn][maxn]; int main() { int n,m,qq; scanf("%d%d%d",&n,&m,&qq); // memset(dp,0,sizeof(dp)); for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ scanf("%1d",&a[i][j]); row[i][j]=row[i][j-1]; if(a[i][j])row[i][j]=0; else row[i][j]++; } // printf("fuck %d\n",i); } //printf("test\n"); for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ for(int p=i;p<=n;p++){ for(int q=j;q<=m;q++){ dp[i][j][p][q]=dp[i][j][p][q-1]+dp[i][j][p-1][q]-dp[i][j][p-1][q-1]; int r=q-j+1; for(int as=p;as>=i;as--){ r=min(r,row[as][q]); dp[i][j][p][q]+=r; } } } } } // printf("test %d\n",qq); for(int i=0;i<qq;i++){ int t1,t2,t3,t4; scanf("%d%d%d%d",&t1,&t2,&t3,&t4); cout<<dp[t1][t2][t3][t4]<<endl; } return 0; }