poj 3695 矩阵切割

题意:给N个矩形,他们可能会重叠,然后给M个询问,每个询问给出指定的矩形位置,然后分别计算每个询问中选中的矩形的并。

矩阵切割就可以了。


#include 
typedef long long ll;
int n,m;
int X1[40],Y1[40],X2[40],Y2[40];
int sum[40];
int a[40];
int r;
void cover(int x1, int y1, int x2, int y2, int k, int c){
    while(k<=r&&(x1>X2[a[k]]||x2Y2[a[k]]||y2 r){
        sum[c] += (x2-x1)*(y2-y1);
        return;
    }
    if(x1 < X1[a[k]]){
        cover(x1, y1, X1[a[k]], y2, k+1, c);
        x1 = X1[a[k]];
    }
    if(x2 > X2[a[k]]){
        cover(X2[a[k]], y1, x2, y2, k+1, c); 
        x2 = X2[a[k]];
    }
    if(y1 < Y1[a[k]]){
        cover(x1, y1, x2, Y1[a[k]], k+1, c);
        y1 = Y1[a[k]];
    }
    if(y2 > Y2[a[k]]){
        cover(x1, Y2[a[k]], x2, y2, k+1, c);
        y2 = Y2[a[k]];
    }
}
int icase;
int main(){
    while(std::cin>>n>>m&&n+m){
        for(int i=1; i<=n; i++) scanf("%d %d %d %d", &X1[i], &Y1[i], &X2[i], &Y2[i]);
        int num;
        int ttt = 0;
        printf("Case %d:\n", ++icase);
        while(m--){
            scanf("%d", &r);
            for(int i=1; i<=r; i++) scanf("%d", &a[i]);
            memset(sum, 0, sizeof(sum));
            for(int i=r; i>=1; i--)
                cover(X1[a[i]], Y1[a[i]], X2[a[i]], Y2[a[i]], i+1, a[i]); 
            ll res = 0;
            for(int i=1; i<=r; i++)
                res += sum[a[i]];
            printf("Query %d: %lld\n", ++ttt, res);
        }
        printf("\n");
    }
    return 0;
}


你可能感兴趣的:(poj题解)