HDU-1264 Counting Squares(矩形面积并模板)

Counting Squares

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 1644    Accepted Submission(s): 817


Problem Description
Your input is a series of rectangles, one per line. Each rectangle is specified as two points(X,Y) that specify the opposite corners of a rectangle. All coordinates will be integers in the range 0 to 100. For example, the line
5 8 7 10
specifies the rectangle who's corners are(5,8),(7,8),(7,10),(5,10).
If drawn on graph paper, that rectangle would cover four squares. Your job is to count the number of unit(i.e.,1*1) squares that are covered by any one of the rectangles given as input. Any square covered by more than one rectangle should only be counted once.
 

Input
The input format is a series of lines, each containing 4 integers. Four -1's are used to separate problems, and four -2's are used to end the last problem. Otherwise, the numbers are the x-ycoordinates of two points that are opposite corners of a rectangle.
 

Output
Your output should be the number of squares covered by each set of rectangles. Each number should be printed on a separate line.
 

Sample Input
   
   
   
   
5 8 7 10 6 9 7 8 6 8 8 11 -1 -1 -1 -1 0 0 100 100 50 75 12 90 39 42 57 73 -2 -2 -2 -2
 

Sample Output
   
   
   
   
8 10000
题意:题目要求平面上几个矩形构成的总面积(矩形会相互覆盖),每行给你两个对角坐标(代表了一个矩形),四个-1代表一组数据结束,输出一个答案。四个-2代表最后一组数据结束,输出答案后结束程序。
我是用用扫描线+线段树做的,但是由于这道题数量很小,坐标最多到100,所以也可以用hash做。但最好掌握扫描线+线段树,这种题都是这样解。
上代码。
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define N 1010 struct Node {     int l,r;     int rl,rr;     int c;     int cnt; } tree[N<<2]; struct Line {     int x;     int y1,y2;     int c; } line[N<<1]; int y[N]; bool cmp(Line a,Line b) {     return a.x<b.x; } void build(int root,int l,int r) {     tree[root].l=l;     tree[root].r=r;     tree[root].rl=y[l];     tree[root].rr=y[r];     tree[root].c=0;     tree[root].cnt=0;     if(l+1==r)         return;     int m=(l+r)>>1;     build(root<<1,l,m);     build(root<<1|1,m,r); } void pushup(int root) {     if(tree[root].c>0)     {             tree[root].cnt=tree[root].rr-tree[root].rl;     }     else     {         if(tree[root].l+1==tree[root].r)         {             tree[root].cnt=0;         }         else         {             tree[root].cnt=tree[root<<1].cnt+tree[root<<1|1].cnt;         }     } } void update(int root,Line a) {     if(tree[root].rl==a.y1&&tree[root].rr==a.y2)     {         tree[root].c+=a.c;         pushup(root);         return;     }     if(a.y2<=tree[root<<1].rr)     {         update(root<<1,a);     }     else if(a.y1>=tree[root<<1|1].rl)     {         update(root<<1|1,a);     }     else     {         Line temp=a;         temp.y2=tree[root<<1].rr;         update(root<<1,temp);         temp=a;         temp.y1=tree[root<<1|1].rl;         update(root<<1|1,temp);     }     pushup(root); } int main() {     int x1,y1,x2,y2;     int flag=0;     while(1)     {         if(flag==1)             break;         int t=1;         while(1)         {             scanf("%d %d %d %d",&x1,&y1,&x2,&y2);             if(x1==-1&&y1==-1&&x2==-1&&y2==-1)                 break;             if(x1==-2&&y1==-2&&x2==-2&&y2==-2)             {                 flag=1;                 break;             }             if(y1>y2)//题目没说两个对角坐标给出的顺序,所以必须考虑所有情况。             {                 int q=y1;                 y1=y2;                 y2=q;             }             if(x1>x2)//一开始以为x1是小是大不影响结果,后来WA后发现错了。如果第一个给的是矩形右边的坐标,那么line[t].c应该为-1
            {                 int q=x1;                 x1=x2;                 x2=q;             }             line[t].x=x1;             line[t].y1=y1;             line[t].y2=y2;             line[t].c=1;             y[t++]=y1;             line[t].x=x2;             line[t].y1=y1;             line[t].y2=y2;             line[t].c=-1;             y[t++]=y2;         }         sort(line+1,line+t,cmp);         sort(y+1,y+t);         build(1,1,t-1);         update(1,line[1]);         int sum=0;         for(int i=2;i<t;i++)         {             sum+=tree[1].cnt*(line[i].x-line[i-1].x);             update(1,line[i]);         }         printf("%d\n",sum);     }     return 0; }

你可能感兴趣的:(ACM,HDU)