Online Judge | Problem Set | Authors | Online Contests | User | ||||||
---|---|---|---|---|---|---|---|---|---|---|
Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest |
必须ac(用c++11才能过)用一个线段树加上一个离散化就可以了 扫描线的基本例题 个人离散化比较喜欢用vector #include<iostream> #include<algorithm> #include<cstdio> #include<cstring> #include<vector> using namespace std; const int N=100010; int n; struct Segment { double x; double y1,y2; int k; bool operator< (const Segment &t)const { return x<t.x; } }seg[N*2]; struct Node { int l; int r; int cnt; double len; }tr[N*8]; vector<double> ys; // 离散化 int find(double y) { return lower_bound(ys.begin(),ys.end(),y)-ys.begin(); // 二分 } void pushup(int u) { if(tr[u].cnt) tr[u].len=ys[tr[u].r+1]-ys[tr[u].l]; else if(tr[u].l == tr[u].r) tr[u].len=0; else tr[u].len=tr[u<<1].len+tr[u<<1|1].len; } void build(int u,int l,int r) { if(l==r) tr[u]={l,r,0,0}; else { tr[u]={l,r}; int mid=(l+r)>>1; build(u<<1,l,mid); build(u<<1|1,mid+1,r); } } void modify(int u,int l,int r,int k) { if(tr[u].l>=l && tr[u].r<=r) { tr[u].cnt+=k; pushup(u); } else { int mid=(tr[u].l+tr[u].r)>>1; if(l<=mid) modify(u<<1,l,r,k); if(r>mid) modify(u<<1|1,l,r,k); pushup(u); } } int main() { int t=0; while(scanf("%d",&n),n) { ys.clear(); for(int i=0,j=0;i<n;i++) { double x1,x2,y1,y2; scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2); seg[j++]={x1,y1,y2,1}; seg[j++]={x2,y1,y2,-1}; ys.push_back(y1); ys.push_back(y2); } sort(ys.begin(),ys.end()); ys.erase(unique(ys.begin(),ys.end()),ys.end()); build(1,0,ys.size()-2); sort(seg,seg+n*2); double res=0; for(int i=0;i<n*2;i++) { if(i>0) res+=tr[1].len*(seg[i].x-seg[i-1].x); modify(1,find(seg[i].y1),find(seg[i].y2)-1,seg[i].k); } cout<<"Test case #"<<++t<<endl; printf("Total explored area: "); printf("%.2lf\n\n",res); } return 0; } Followed by: Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator