Red Huang

Red Huang

Codeforces Round #219 (Div. 2) D. Counting Rectangles is Fun

網路上大家都說先預處理,重點是要怎麼預處理才是重點阿 我不會啊~~~

不過在此終於懂了一些

image

1. 先算出每一個單元格跟他上面的單元格能夠構出幾個矩形,遇到 1 就要變成 0

2. 然後再利用四個方向大枚舉 u,l,d,r 利用右下角的點算出最多能夠與這四個方向以內的單元格構出多少個矩形

所以只要利用剛剛第一步驟算好的點 加上當前最小值,遇到 0 就不要再算了

3. 加上 u,l,d-1,r  u,l,d,r-1 的個數,當然 這些已經處理過了 (而這些處理過的點 需要處理的點也都已經處理過了 (DP 概念)),而且因為會有重疊的部分所以必須扣掉 u,l,d-1,r-1

/\*  
 \* GCA : "Computer is artificial subject absolutely,Math is God"  
 \*/  
#include <iostream>  
#include <cstdio>  
#include <cstring>  
#include <algorithm>  
#include <cmath>  
#include <climits>  
#include <vector>  
#include <set>  
#include <map>  
#include <queue>  
#include <cctype>  
#include <utility>  
#include <ctime>  
using namespace std;  
#ifdef DEBUG  
#define VAR(a,b) \_\_typeof(b) a=(b)  
#define debug(...) printf("DEBUG: "),printf(\_\_VA\_ARGS\_\_)  
#else  
#define VAR(a,b) \_\_typeof(b) a=(b)  
#define debug(...)  
#endif  
typedef unsigned int uint;  
typedef long long int Int;  
typedef unsigned long long int UInt;  
#define Set(a,s) memset(a,s,sizeof(a))  
#define Pln() printf("\\n")  
#define For(i,x)for(int i=0;i<x;i++)  
#define CON(x,y) x##y  
#define M 45  
#define PB push\_back  
#define oo INT\_MAX  
#define FOR(a,b) for(VAR(a,(b).begin());a!=(b).end();++a)  
#define eps 1e-9  
#define X first  
#define Y second  
inline bool xdy(double x,double y){return x>y+eps;}  
inline bool xddy(double x,double y){return x>y-eps;}  
inline bool xcy(double x,double y){return x<y-eps;}  
inline bool xcdy(double x,double y){return x<y+eps;}  
const Int mod=1000000007;  
int n,m,q;  
char mz\[M\]\[M\];  
int dp\[M\]\[M\]\[M\]\[M\];  
int cnt\[M\]\[M\];  
void pre(){  
    Set(dp,0);  
    Set(cnt,0);  
    for(int i=1;i<=n;i++){  
        for(int j=1;j<=m;j++){  
            if(mz\[i-1\]\[j-1\]=='0')cnt\[i\]\[j\]=cnt\[i-1\]\[j\]+1;  
            else cnt\[i\]\[j\]=0;  
        }  
    }  
    for(int u=1;u<=n;u++){  
        for(int l=1;l<=m;l++){  
            for(int d=u;d<=n;d++){  
                for(int r=l;r<=m;r++){  
                    int minn=d-u+1;  
                    int all=0;  
                    for(int k=r;k>=l;k--){  
                        minn=min(minn,cnt\[d\]\[k\]);  
                        if(minn==0)break;  
                        all+=minn;  
                    }  
                    dp\[u\]\[l\]\[d\]\[r\]=dp\[u\]\[l\]\[d-1\]\[r\]+dp\[u\]\[l\]\[d\]\[r-1\]-dp\[u\]\[l\]\[d-1\]\[r-1\]+all;  
                }  
            }  
        }  
    }  
}  
int main() {  
    ios\_base::sync\_with\_stdio(0);  
    while(~scanf("%d%d%d",&n,&m,&q)){  
        for(int i=0;i<n;i++){  
            scanf("%s",mz\[i\]);  
        }  
        pre();  
        while(q--){  
            int a,b,c,d;  
            scanf("%d%d%d%d",&a,&b,&c,&d);  
            printf("%d\\n",dp\[a\]\[b\]\[c\]\[d\]);  
        }  
    }  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
}  

加载中...
此文章数据所有权由区块链加密技术和智能合约保障仅归创作者所有。