1 条题解
-
0
题意:给出若干矩形的对角线的坐标;求出矩形面积并; 解题思路:我们首先想到扫描线算法,利用计算机只能处理离散量的特性,所以我们将矩形离散成事件点:矩形的左,右两边的横坐标,纵坐标,另外,纵坐标是需要离散化的;扫描线第一次扫描到左边时,将这一段长度加入用线段树维护的数组中,这样可以保证不遗漏任何面积,也不会重复计算面积,扫到右边时,删除线段; 代码:
#include<stdio.h> #include<memory.h> #include<algorithm> #define MAXN 11000 using namespace std; struct Rect{ long long x1,x2,y1,y2; }; struct event{ long long x,y1,y2; long long add; }; struct segtree{ long long count,total;//count表示当前线段树中还有多少个矩形,total表示扫描线的长度; }; long long n=0; Rect rect[MAXN]; event evi[2*MAXN]; segtree tree[2*MAXN]; long long id[2*MAXN]; bool cmp(event a,event b) { return a.x<b.x; } void up(long long i,long long lb,long long rb) { tree[i].total=tree[i*2].total+tree[i*2+1].total; if(tree[i].count) tree[i].total=abs(id[rb]-id[lb]); } void ins(long long i,long long lb,long long rb,long long a,long long b,long long k)//线段树更新 { if(lb==a&&rb==b) { tree[i].count+=k; up(i,lb,rb); return; } long long med=(lb+rb)/2; if(b<=med) ins(2*i,lb,med,a,b,k); else if(a>=med) ins(2*i+1,med,rb,a,b,k); else { ins(2*i,lb,med,a,med,k); ins(2*i+1,med,rb,med,b,k); } up(i,lb,rb); } long long area() { for(long long i=0;i<n;i++) { id[i]=rect[i].y1; id[i+n]=rect[i].y2; } sort(id,id+2*n); for(long long i=0;i<2*n;i++)//离散化 { rect[i].y1=lower_bound(id,id+2*n,rect[i].y1)-id; rect[i].y2=lower_bound(id,id+2*n,rect[i].y2)-id; } for(long long i=0;i<n;i++) { evi[i].add=1; evi[i+n].add=-1; evi[i].x=rect[i].x1; evi[i+n].x=rect[i].x2; evi[i].y1=evi[i+n].y1=rect[i].y1; evi[i].y2=evi[i+n].y2=rect[i].y2; } sort(evi,evi+n*2,cmp); long long ans=0; for(long long i=0;i<2*n;i++) { if(i>0&&evi[i].x>evi[i-1].x) ans+=(evi[i].x-evi[i-1].x)*tree[1].total; long long a=min(evi[i].y1,evi[i].y2); long long b=max(evi[i].y1,evi[i].y2); ins(1,0,2*n-1,a,b,evi[i].add); } return ans; } int main() { long long a,b,c,d,i=0; bool flag; while(1) { memset(tree,0,sizeof(tree)); memset(rect,0,sizeof(rect)); memset(evi,0,sizeof(evi)); memset(id,0,sizeof(id)); n=0;i=0; flag=false; while(1) { scanf("%lld%lld%lld%lld",&a,&b,&c,&d); if(a==-1&&!flag) { return 0; } else if(a==-1) break; else { rect[i].x1=a; rect[i].y1=b; rect[i].x2=c; rect[i++].y2=d; n++; flag=true; } } printf("%lld\n",area()); } return 0; }
- 1
信息
- ID
- 390
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 2
- 已通过
- 1
- 上传者