POJ 3695 Rectangles(矩形切割)

来源:互联网 发布:好用的linux 知乎 编辑:程序博客网 时间:2024/05/16 10:07
Rectangles
Time Limit: 2000MS Memory Limit: 65536KTotal Submissions: 3927 Accepted: 1150

Description

You are developing a software for painting rectangles on the screen. The software supports drawing several rectangles and filling some of them with a color different from the color of the background. You are to implement an important function. The function answer such queries as what is the colored area if a subset of rectangles on the screen are filled.

Input

The input consists of multiple test cases. Each test case starts with a line containing two integersN(1 ≤ N ≤ 20) and M(1 ≤ M ≤ 100000), indicating the number of rectangles on the screen and the number of queries, respectively.
The i-th line of the following N lines contains four integers X1,Y1,X2,Y2 (0 ≤X1 < X2 ≤ 1000, 0 ≤ Y1 < Y2 ≤ 1000), which indicate that the lower-left and upper-right coordinates of thei-th rectangle are (X1, Y1) and (X2, Y2). Rectangles are numbered from 1 toN.
The last M lines of each test case describe M queries. Each query starts with a integerR(1<=RN), which is the number of rectangles the query is supposed to fill. The following list ofR integers in the same line gives the rectangles the query is supposed to fill, each integer of which will be between 1 andN, inclusive.

The last test case is followed by a line containing two zeros.

Output

For each test case, print a line containing the test case number( beginning with 1).
For each query in the input, print a line containing the query number (beginning with 1) followed by the corresponding answer for the query. Print a blank line after the output for each test case.

Sample Input

2  20 0 2 21 1 3 31 12 1 22 10 1 1 22 1 3 22 1 20 0

Sample Output

Case 1:Query 1: 4Query 2: 7Case 2:Query 1: 2


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

【解题方法】如上,直接粘模板让我WA了很多次啊,之后又TLE,看了讨论知道用C++可以过,果然1200ms过掉了。

【AC 代码】

#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;typedef long long LL;struct node{    LL x1,y1,x2,y2;    LL sum;    void read()    {        scanf("%I64d%I64d%I64d%I64d",&x1,&y1,&x2,&y2);    }}T[44];LL n,m;LL a[44];LL xx;void Cover(LL x1,LL y1,LL x2,LL y2,LL k,LL c){    while(k<xx&&(x1>=T[a[k]].x2||x2<=T[a[k]].x1||y1>=T[a[k]].y2||y2<=T[a[k]].y1)) k++;    if(k>=xx){        T[a[c]].sum+=(x2-x1)*(y2-y1);        return ;    }    if(x1<T[a[k]].x1){        Cover(x1,y1,T[a[k]].x1,y2,k+1,c);        x1=T[a[k]].x1;    }    if(x2>T[a[k]].x2){        Cover(T[a[k]].x2,y1,x2,y2,k+1,c);        x2=T[a[k]].x2;    }    if(y1<T[a[k]].y1){        Cover(x1,y1,x2,T[a[k]].y1,k+1,c);        y1=T[a[k]].y1;    }    if(y2>T[a[k]].y2){        Cover(x1,T[a[k]].y2,x2,y2,k+1,c);        y2=T[a[k]].y2;    }}int main(){    LL ks1=1,ks2;    while(scanf("%I64d%I64d",&n,&m)!=EOF)    {        if(n==0&&m==0) break;        memset(T,0,sizeof(T));        for(int i=0; i<n; i++) T[i].read();        printf("Case %I64d:\n",ks1++);        ks2=1;        while(m--)        {            memset(a,0,sizeof(a));            for(int i=0; i<n; i++) T[i].sum=0LL;            scanf("%I64d",&xx);            for(int i=0; i<xx; i++){                scanf("%I64d",&a[i]);                a[i]--;            }            for(LL i=xx-1; i>=0; i--){                Cover(T[a[i]].x1,T[a[i]].y1,T[a[i]].x2,T[a[i]].y2,i+1,i);            }            LL ans=0;            for(int i=0; i<xx; i++){                ans+=T[a[i]].sum;            }            printf("Query %I64d: %I64d\n",ks2++,ans);        }        printf("\n");    }    return 0;}



0 0
原创粉丝点击