扫描线求面积的并,交

扫描线求面积的并:题目

模板:

 1 #include <iostream>
 2 #include <algorithm>
 3 using namespace std;
 4 typedef long long ll;
 5 const int maxn = 210;
 6 int n;
 7 double x[maxn<<2];
 8 struct node{
 9     double l,r,h;
10     int flag;
11 }nd[maxn<<2];
12 
13 bool cmp(node u, node v)
14 {
15     return u.h<v.h;
16 }
17 
18 struct tree{
19     int l,r,cnt;
20     double len;
21 }tree[maxn<<2];
22 
23 void build(int rt,int left,int right){
24     tree[rt].l=left;
25     tree[rt].r=right;
26     tree[rt].len=0;
27     tree[rt].cnt=0;
28     if( left==right ) return ;
29     int mid=(left+right)>>1;
30     build(rt<<1,left,mid);
31     build(rt<<1|1,mid+1,right);
32 }
33 
34 int findPos(int l,int r,double val){
35     int mid;
36     while( l<=r ){
37         mid=(l+r)>>1;
38         if( x[mid]>val ) r=mid-1;
39         else if( x[mid]<val ) l=mid+1;
40         else break;
41     }
42     return mid;
43 }
44 
45 void pushUp(int rt){
46     if( tree[rt].cnt ){//非0,整段覆盖
47         tree[rt].len=x[tree[rt].r+1]-x[tree[rt].l];
48     }
49     else if( tree[rt].l==tree[rt].r )//叶子
50         tree[rt].len=0;
51     else tree[rt].len=tree[rt<<1].len+tree[rt<<1|1].len;
52 }
53 
54 void update(int rt,int left,int right,int val){
55     if( left<=tree[rt].l && tree[rt].r<=right ){
56         tree[rt].cnt+=val;
57         pushUp(rt);
58         return ;
59     }
60     int mid=(tree[rt].l+tree[rt].r)>>1;
61     if( left<=mid ) update(rt<<1,left,right,val);
62     if( right>mid ) update(rt<<1|1,left,right,val);
63     pushUp(rt);
64 }
65 
66 int main()
67 {
68     int cas=0;
69     int l,r;
70     double x1,x2,y1,y2;
71     while( ~scanf("%d",&n)&&n){
72         int cnt=0;
73         for(int i=1;i<=n;i++){
74             scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
75             x[++cnt]=x1;
76             nd[cnt].l=x1;
77             nd[cnt].r=x2;
78             nd[cnt].h=y1;
79             nd[cnt].flag=1;//下边
80             x[++cnt]=x2;
81             nd[cnt].l=x1;
82             nd[cnt].r=x2;
83             nd[cnt].h=y2;
84             nd[cnt].flag=-1;//上边
85         }
86         sort(x+1,x+1+cnt);
87         sort(nd+1,nd+1+cnt,cmp);
88         build(1,1,cnt);
89         double ans=0;
90         for(int i=1;i<=cnt;i++){
91             l=findPos(1,cnt,nd[i].l);
92             r=findPos(1,cnt,nd[i].r)-1;
93             update(1,l,r,nd[i].flag);
94             ans += tree[1].len*(nd[i+1].h-nd[i].h);
95         }
96         printf("Test case #%d
Total explored area: %.2f

",++cas,ans);
97     }
98     return 0;
99 }

扫描线先求面积的交:题目

模板:

  1 #include<iostream>
  2 #include<cstring>
  3 #include<cstdio>
  4 #include<algorithm>
  5 using namespace std;
  6 typedef long long ll;
  7 
  8 const int maxn=2010;
  9 int n, cnt;
 10 double x[maxn<<2];
 11 struct Node{
 12     double l,r,y;
 13     int flag;
 14 }node[maxn<<2];
 15 
 16 int cmp(Node a ,Node b){
 17     return a.y<b.y;
 18 }
 19 
 20 struct Tree{
 21     int l, r;
 22     double add,len1,len2;
 23 }tree[maxn<<2];
 24 
 25 int findPos(double val)//找val在x[]中出现的位置
 26 {
 27     int l=1, r=cnt;
 28     int mid;
 29     while(l<=r)
 30     {
 31         mid=(l+r)>>1;
 32         if(x[mid]<val) l=mid+1;
 33         else if(x[mid]>val) r=mid-1;
 34         else break;
 35     }
 36     return mid;
 37 }
 38 
 39 void build(int rt, int left, int right)
 40 {
 41     tree[rt].l=left;
 42     tree[rt].r=right;
 43     tree[rt].add=tree[rt].len1=tree[rt].len2=0;//全置0
 44     if(left==right)//叶子
 45     {
 46         return ;
 47     }
 48     int mid=(left+right)>>1;
 49     build(rt<<1,left,mid);
 50     build(rt<<1|1,mid+1,right);
 51 }
 52 void pushUp(int rt)
 53 {
 54     if(tree[rt].add>=2) tree[rt].len1=tree[rt].len2=x[tree[rt].r+1]-x[tree[rt].l];
 55     else if(tree[rt].add==1){
 56         tree[rt].len1=x[tree[rt].r+1]-x[tree[rt].l];
 57         if(tree[rt].l==tree[rt].r) tree[rt].len2=0;
 58         else tree[rt].len2=tree[rt<<1].len1+tree[rt<<1|1].len1;
 59     }
 60     else{
 61         if(tree[rt].l==tree[rt].r) tree[rt].len1=tree[rt].len2=0;
 62         else{
 63             tree[rt].len1=tree[rt<<1].len1+tree[rt<<1|1].len1;
 64             tree[rt].len2=tree[rt<<1].len2+tree[rt<<1|1].len2;
 65         }
 66     }
 67 }
 68 
 69 void update(int rt,int left,int right,int val){
 70     if(left<=tree[rt].l && tree[rt].r<=right){
 71         tree[rt].add+=val;
 72         pushUp(rt);
 73         return ;
 74     }
 75     int mid=(tree[rt].l+tree[rt].r)>>1;
 76     if( left<=mid ) update(rt<<1,left,right,val);
 77     if( right>mid ) update(rt<<1|1,left,right,val);
 78     pushUp(rt);
 79 }
 80 
 81 int main()
 82 {
 83     double x1,x2,y1,y2;
 84     int l,r,t;
 85     scanf("%d",&t);
 86     while(t--){
 87         cnt=0;
 88         memset(node, 0, sizeof(node));
 89         memset(tree, 0, sizeof(tree));
 90         scanf("%d",&n);
 91         for(int i=1;i<=n;i++){
 92             scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
 93             x[++cnt]=x1;
 94             node[cnt].l=x1;
 95             node[cnt].r=x2;
 96             node[cnt].y=y1;
 97             node[cnt].flag=1;//左边
 98             x[++cnt]=x2;
 99             node[cnt].l=x1;
100             node[cnt].r=x2;
101             node[cnt].y=y2;
102             node[cnt].flag=-1;//右边
103         }
104         sort(x+1,x+cnt+1);
105         sort(node+1,node+cnt+1,cmp);
106         build(1,1,cnt);
107         double ans=0;
108 
109         l=findPos(node[1].l);
110         r=findPos(node[1].r)-1;
111         update(1,l,r,node[1].flag);
112         for(int i=2;i<=2*n;i++){
113             ans+=tree[1].len2*(node[i].y-node[i-1].y);
114             l=findPos(node[i].l);
115             r=findPos(node[i].r)-1;
116             update(1, l, r, node[i].flag);
117         }
118         printf("%.2f
", ans);
119     }
120     return 0;
121 }
原文地址:https://www.cnblogs.com/wsy107316/p/13292496.html