Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 8759 | Accepted: 3457 |
Description
Input
Output
Sample Input
2 10 10 20 20 15 15 25 25.5 0
Sample Output
Test case #1 Total explored area: 180.00
Source
分析:此题与1177类似,这回试着以节点来构造线段树,这样速度较快,而且就适用于带小数的线段了
更新了下代码
#include<cstdio> #include<iostream> #include<algorithm> #define ls rt<<1 #define rs rt<<1|1 #define lson l,m,ls #define rson m,r,rs using namespace std; const int mm=222; const int mn=mm<<2; struct seg { double x,y1,y2; int v; }g[mm]; double y[mm],sum[mn],L,R; int t[mn],val; void build() { for(int i=0;i<mn;++i)sum[i]=t[i]=0; } void updata(int l,int r,int rt) { if(l>=r)return; if(L<=y[l]&&R>=y[r])t[rt]+=val; else { int m=(l+r)>>1; if(L<y[m])updata(lson); if(R>y[m])updata(rson); } if(t[rt])sum[rt]=y[r]-y[l]; else if(l==r)sum[rt]=0; else sum[rt]=sum[ls]+sum[rs]; } bool cmp(seg a,seg b) { return a.x<b.x; } int main() { int i,j,n,m,cs=0; double ans; while(scanf("%d",&n),n) { for(j=i=0;i<n;++i,j+=2) { scanf("%lf%lf%lf%lf",&g[j].x,&y[j],&g[j+1].x,&y[j+1]); g[j].y1=g[j+1].y1=y[j]; g[j].y2=g[j+1].y2=y[j+1]; g[j].v=1,g[j+1].v=-1; } sort(y,y+j); sort(g,g+j,cmp); for(m=i=0;i<j;++i) if(y[m]<y[i])y[++m]=y[i]; build(); for(ans=i=0;i<j;++i) { L=g[i].y1,R=g[i].y2,val=g[i].v; updata(0,m,1); if(g[i].x<g[i+1].x)ans+=(g[i+1].x-g[i].x)*sum[1]; } printf("Test case #%d\nTotal explored area: %.2lf\n\n",++cs,ans); } return 0; }
贴下代码:
#include <cstdio> #include <algorithm> using namespace std; const int maxn=200; const int maxtree=666; struct tree { int l,r,t; float m; } lt[maxtree]; struct data { float d,y1,y2; bool o; } x[maxn]; float y[maxn],l,r; int c; void maketree(int v,int l,int r) { lt[v].l=l,lt[v].r=r,lt[v].t=lt[v].m=0; if(l+1==r)return; int m=(l+r)>>1,now=v<<1; maketree(now,l,m); maketree(now+1,m,r); } inline void updata(int v) { if(lt[v].t)lt[v].m=y[lt[v].r]-y[lt[v].l]; else if(lt[v].l+1==lt[v].r)lt[v].m=0; else lt[v].m=lt[v<<1].m+lt[v*2+1].m; } void ltwork(int v) { if(l<=y[lt[v].l]&&y[lt[v].r]<=r)lt[v].t+=c; else { int now=v<<1; if(l<y[lt[now].r])ltwork(now); if(r>y[lt[now].r])ltwork(now+1); } updata(v); } bool cmp(data a,data b) { return a.d<b.d; } int main(int argc, char* argv[]) { int i,j,n,gk,cc=0; double ans; freopen("a.in","r",stdin); freopen("a.out","w",stdout); while(scanf("%d",&n),n) { for(i=j=0; i<n; ++i,j+=2) { scanf("%f%f%f%f",&x[j].d,&y[j],&x[j+1].d,&y[j+1]); x[j].y1=x[j+1].y1=y[j]; x[j].y2=x[j+1].y2=y[j+1]; x[j].o=0,x[j+1].o=1; } sort(y,y+j); sort(x,x+j,cmp); for(i=gk=1; i<j; ++i) if(y[i]>y[i-1])y[gk++]=y[i]; maketree(1,0,gk-1); for(i=ans=0; i<j; ++i) { if(!(c=x[i].o))c=-1; l=x[i].y1,r=x[i].y2,ltwork(1); if(x[i+1].d>x[i].d)ans+=(x[i+1].d-x[i].d)*(double)lt[1].m; } printf("Test case #%d/nTotal explored area: %0.2lf/n/n",++cc,ans); } return 0; }
此题数据较小,也可不用线段树(好像~~~):
#include <cstdio> #include <algorithm> using namespace std; float a1[202],a2[202],b1[202],b2[202],t1[404],t2[404]; int main() { int n,t,i,j,k,c=0; while(scanf("%d",&n),n) { for(i=t=0;i<n;++i) { scanf("%f%f%f%f",&a1[i],&b1[i],&a2[i],&b2[i]); t1[t] = a1[i]; t2[t] = b1[i]; ++t; t1[t] = a2[i]; t2[t] = b2[i]; ++t; } sort(t1,t1+t); sort(t2,t2+t); double areaa = 0; for(i=0;i<t-1;++i) for(j=0;j<t-1;++j) for(k=0;k<n;++k) if((t1[i]>=a1[k])&&(t2[j]>=b1[k])&&(t1[i+1]<=a2[k])&&(t2[j+1]<=b2[k])) { areaa+=((double)(t1[i+1]-t1[i]))*(t2[j+1]-t2[j]); break; } printf("Test case #%d/nTotal explored area: %0.2lf/n/n",++c,areaa); } return 0; }