标签:several node 重复 title cep panel sar memset 更新
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 18275 Accepted Submission(s): 7409
离散化x轴,然后扫描线,具体实现看代码
//#include<bits/stdc++.h> #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; typedef long long ll; const int maxn=200+10; int cnt[maxn*4],n;//记录某个区间的下底边比上底边多的个数 double sum[maxn*4];//记录某个区间下底边比上底边多的个数总长度 double Hash[maxn];//对横坐标x离散化 struct node{ double l,r,h; int f; node(){} node(double x1,double x2,double hh,int ff):l(x1),r(x2),h(hh),f(ff){} bool operator<(const node &a)const{ return h<a.h; } }s[maxn*4]; void init(){ memset(sum,0,sizeof(sum)); memset(cnt,0,sizeof(cnt)); } void pushup(int x,int l,int r){ if(cnt[x]) sum[x]=Hash[r+1]-Hash[l];//表示该区间整个线段长度可作为底边 else if(l==r) sum[x]=0;//叶子结点区间长度为0,则底边长度为0 else sum[x]=sum[x*2]+sum[x*2+1]; } void update(int x,int L,int R,int f,int l,int r){ if(L<=l&&r<=R){ cnt[x]+=f; pushup(x,l,r); return ; } int mid=(l+r)/2; if(L<=mid) update(x*2,L,R,f,l,mid); if(R>mid) update(x*2+1,L,R,f,mid+1,r); pushup(x,l,r); } int main(){ double x1,x2,y1,y2; int p=0; while(cin>>n&&n){ init();int k=0; while(n--){ scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2); if(x1>x2) swap(x1,x2); if(y1>y2) swap(y1,y2); Hash[k]=x1; s[k++]=node(x1,x2,y1,1); Hash[k]=x2; s[k++]=node(x1,x2,y2,-1); } sort(s,s+k);//把线段按高度h从小到大排序 sort(Hash,Hash+k);//把x坐标从小到大排序 int ans=unique(Hash,Hash+k)-Hash;//去重复端点 double SUM=0; printf("Test case #%d\n",++p); for(int i=0;i<k;i++){ int l=lower_bound(Hash,Hash+ans,s[i].l)-Hash; int r=lower_bound(Hash,Hash+ans,s[i].r)-Hash; update(1,l,r-1,s[i].f,0,ans-1);//扫描线段更新可用底边长 SUM+=sum[1]*(s[i+1].h-s[i].h);//新增加面积 } printf("Total explored area: %.2f\n\n",SUM); } return 0; }
标签:several node 重复 title cep panel sar memset 更新
原文地址:https://www.cnblogs.com/weimeiyuer/p/9449365.html