扫描线求周长,题干又问题,没说要多组输入啊,不多组输入就wr,让我找了好长时间
#include <iostream> #include <algorithm> #include <cstdio> #include <algorithm> using namespace std; const int maxn=2e4+100; struct note { int l,r,h; int ff; note() {} note(int l,int r,int h,int ff):l(l),r(r),h(h),ff(ff) {} bool operator < (const note &p) const { return h<p.h; } } aa[maxn]; int col[maxn<<2],sum[maxn<<2],ll[maxn<<2],rr[maxn<<2]; int linenum[maxn<<2]; void pushup(int l,int r,int rt) { if(col[rt]) { sum[rt]=r-l+1; linenum[rt]=2; ll[rt]=rr[rt]=1; } else if(l==r) { sum[rt]=linenum[rt]=ll[rt]=rr[rt]=0; } else { sum[rt]=sum[rt<<1]+sum[rt<<1|1]; ll[rt]=ll[rt<<1]; rr[rt]=rr[rt<<1|1]; linenum[rt]=linenum[rt<<1]+linenum[rt<<1|1]; if(rr[rt<<1]&&ll[rt<<1|1]) linenum[rt]-=2;//两条线能接在一起,那么将内侧的边减去 } } void update(int L,int R,int v,int l,int r,int rt) { if(L<=l&&r<=R) { col[rt]+=v; pushup(l,r,rt); return; } int mid=(l+r)>>1; if(L<=mid) update(L,R,v,l,mid,rt<<1); if(R>mid) update(L,R,v,mid+1,r,rt<<1|1); pushup(l,r,rt); } int n; int main() { while(~scanf("%d",&n)) { int mini=10000,maxi=-10000; int a,b,c,d; int cnt=0; for(int i=1; i<=n; i++) { scanf("%d%d%d%d",&a,&b,&c,&d); cnt++; aa[cnt]=note(a,c,b,1); cnt++; aa[cnt]=note(a,c,d,-1); mini=min(mini,a); maxi=max(maxi,c); } sort(aa+1,aa+1+cnt); int ans=0; int zz=0; for(int i=1; i<=cnt; i++) { if(aa[i].l<aa[i].r) update(aa[i].l,aa[i].r-1,aa[i].ff,mini,maxi,1); ans+=abs(zz-sum[1]); ans+=linenum[1]*(aa[i+1].h-aa[i].h); zz=sum[1]; } printf("%d\n",ans); } return 0; }