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 |
郁闷,一直WA,用线段树写的,我知道哪组数据过不了,但不知道原因,求人分析代码,有详细的注释~~~跪求~~#include "stdio.h" #include "malloc.h" #include "stdlib.h" #include "string.h" typedef struct segtree{//线段树的结构 int count; int m; int line; int lb,rb; int l,r; struct segtree *lc,*rc; }*st,stnode; typedef struct rec{//矩形的结构 int x1,x2; int y1,y2; }rect; typedef struct lin{//每条竖线的结构 int y1,y2; int in; int x; }vet; //====================================线段树的操作================================== void updatem(st &); void updateline(st&); st creatit(int i,int j){//建树 int k; st now=(st)malloc(sizeof(stnode)); now->l=i; now->r=j; now->count=0; now->m=0; now->line=0; now->lb=0; now->rb=0; now->lc=NULL; now->rc=NULL; if(j-i>1){ k=(i+j)/2; if(i<k){ now->lc=creatit(i,k); } if(j>k){ now->rc=creatit(k,j); } } return now; } int dropit(st &s){//销毁树 if(s->lc!=NULL) dropit(s->lc); if(s->rc!=NULL) dropit(s->rc); free(s); return 0; } int insertit(st &s,int i,int j){//插入线段 int k; if(s==NULL) return 0; if(i<=s->l&&j>=s->r){ s->count++; }else{ k=(s->l+s->r)/2; if(i<k){ insertit(s->lc,i,j); } if(j>k){ insertit(s->rc,i,j); } } updatem(s); updateline(s); return 1; } int deleteit(st &s,int i,int j){//删除线段 int k; if(s==NULL) return 0; if(i<=s->l&&j>=s->r){ s->count--; }else{ k=(s->l+s->r)/2; if(i<k){ deleteit(s->lc,i,j); } if(j>k){ deleteit(s->rc,i,j); } } updatem(s); updateline(s); return 1; } void updatem(st &s){//更新度 if(s->count>0){ s->m=s->r-s->l; } else{ if(s->r-s->l==1){ s->m=0; }else{ s->m=s->lc->m+s->rc->m; } } } void updateline(st &s){//更新line if(s->count>0){ s->line=1; s->lb=1; s->rb=1; }else{ if(s->r-s->l==1){ s->line=0; s->lb=0; s->rb=0; } else{ s->lb=s->lc->lb; s->rb=s->rc->rb; s->line=s->lc->line+s->rc->line-s->lc->rb*s->rc->lb; } } } int getinm(st s,int i,int j){//求i到j的度 int r=0; int k; k=(s->l+s->r)/2; if(i<=s->l&&j>=s->r){ r+=s->m; return r; } if(i>=s->r||j<=s->l){ return r; } if(i<k) r+=getinm(s->lc,i,j); if(j>k) r+=getinm(s->rc,i,j); return r; } int getinline(st s,int i,int j){//求i到j的line int r=0; int k; k=(s->l+s->r)/2; if(i<=s->l&&j>=s->r){ r+=s->line; return r; } if(i>=s->r||j<=s->l){ return r; } if(i<k) r+=getinline(s->lc,i,j); if(j>k) r+=getinline(s->rc,i,j); return r; } //============================================================================= int n;//矩形的个数 int nn;//涉及到的横坐标的个数 rect r;//一个矩形 int tmap[10000];//临时存储的横坐标 int xmap[10000];//去除了重复后的横坐标 vet v[10000];//所有矩形竖线 int cmp(const void *a,const void *b){ return *(int*)a-*(int*)b; } int cmpv(const void *a,const void *b){ vet & x=*(vet*)a; vet & y=*(vet*)b; return x.x-y.x; } int abss(int a){//求绝对值 if(a<0) return -a; else return a; } int main(){ int i,j; int lastm,lastline,nowm,nowline; st l; int re=0; int miny=99999,maxy=-99999; while(scanf("%d",&n)!=EOF){ if(n>0){ for(i=0;i<n;i++){ scanf("%d%d%d%d",&r.x1,&r.y1,&r.x2,&r.y2); //分出横坐标 tmap[i*2]=r.x1; tmap[i*2+1]=r.x2; //分出竖线 v[i*2].in=1; v[i*2].x=r.x1; v[i*2].y1=r.y1; v[i*2].y2=r.y2; v[i*2+1].in=0; v[i*2+1].x=r.x2; v[i*2+1].y1=r.y1; v[i*2+1].y2=r.y2; //找出y的范围 if(r.y1<miny) miny=r.y1; if(r.y2>maxy) maxy=r.y2; } qsort(tmap,n*2,sizeof(int),cmp); qsort(v,n*2,sizeof(vet),cmpv); //======================debug================================= for(i=0;i<2*n;i++){ printf("%d\n",i); printf("%d %d %d %d\n",v[i].x,v[i].y1,v[i].y2,v[i].in); } //============================================================ xmap[0]=tmap[0]; for(i=1,j=0;i<2*n;i++){//得到去除了重复值的横坐标 if(tmap[i]!=xmap[j]){ j++; xmap[j]=tmap[i]; } } nn=j+1; l=creatit(miny,maxy); lastm=0; lastline=0; for(i=0,j=0;i<nn;i++){//遍历每个横坐标 for(;j<2*n;j++){//遍历该横坐标上的竖线 if(v[j].x!=xmap[i]) break; if(v[j].in==1)//插入线段 insertit(l,v[j].y1,v[j].y2); if(v[j].in==0)//删除线段 deleteit(l,v[j].y1,v[j].y2); } nowline=l->line; nowm=l->m; if(i!=nn-1) re+=((xmap[i+1]-xmap[i])*2*nowline);//不是最后一个,就把横向线段长度添加到结果里 re+=abss(nowm-lastm);//添加竖向的线段长度 lastm=nowm; lastline=nowline; } } printf("%d\n",re); } dropit(l); return 0; } //=======================我过不了的数据=================================== 47 -1105 -1155 -930 -285 -765 -1115 -615 -375 -705 -480 -165 -285 -705 -1200 -175 -1025 -275 -1105 -105 -385 -10 -1165 185 -285 315 -1160 400 -710 340 -1195 655 -1070 580 -1140 655 -265 325 -480 395 -335 365 -390 620 -265 365 -770 610 -665 815 -1195 1110 -1070 825 -760 1100 -660 810 -405 1115 -275 780 -700 860 -360 1065 -695 1130 -360 775 -1110 860 -735 1070 -1110 1145 -730 -1065 -95 140 260 -725 80 750 460 135 -135 490 840 135 -135 490 750 -520 40 -210 945 -595 620 215 695 670 -5 855 610 550 -75 830 -25 815 240 1085 370 980 -90 1125 145 280 150 490 315 -1035 -155 -845 -90 855 815 950 1030 785 980 860 1165 945 985 1015 1160 730 835 1075 895 875 695 935 790 -1165 420 -520 650 -1090 815 -210 945 -130 800 65 1160 120 980 690 1150 -1140 995 -125 1180 -825 1050 -195 1135 -90 865 10 1090 280 1045 625 1090 -655 1065 -245 1115 -1155 70 -790 315 -1005 110 -825 225 我输出:36790 该输出:37000 Followed by:
Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator