1. 程式人生 > >HDU 1542 -Atlantis(線掃描)

HDU 1542 -Atlantis(線掃描)

explore ace sca upd void pri algorithm AI 有一點

鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=1542

題意:給你n個矩形,求它們覆蓋的面積為多少。(註意輸出有要求:在 每個測試例子之後輸出一個空行)///由於這裏的原因讓自己PE了一發

這是赤裸裸的線掃描問題,沒有一點地方可以小心的,除了上述說的輸出格式的要求。

線掃描其實就是線段樹的一種技巧。

  1 #include<cstdio>
  2 #include<algorithm>
  3 
  4 using namespace std;
  5 #define lson id*2
  6 #define rson id*2+1
  7
const int maxn=200+5; 8 int n; 9 double x[maxn]; 10 11 struct Line 12 { 13 double x1,x2,y;///線段的左右端點的值以及高度 14 operator<(const Line &a)const 15 { 16 return y<a.y; 17 }///升序排列 18 int flag;///標記線段是矩形得到下邊(1)還是上邊(-1) 19 }line[maxn]; 20 21 struct Trie 22 { 23 int
l,r;///線段樹的左右端點 24 double dl,dr;///線段的左右端點的值 25 double len;///線段的長度 26 int cov;///線段被覆蓋的次數 27 }a[maxn*4]; 28 29 void Get_Len(int id) 30 { 31 if(a[id].cov>0) 32 a[id].len=a[id].dr-a[id].dl; 33 else if(a[id].l+1==a[id].r) 34 a[id].len=0; 35 else 36 a[id].len=a[lson].len+a[rson].len;
37 } 38 void Build(int id,int l,int r) 39 { 40 a[id].cov=0; 41 a[id].dl=x[l]; 42 a[id].dr=x[r]; 43 a[id].l=l; 44 a[id].r=r; 45 a[id].len=0; 46 if(l+1==r) 47 return ; 48 int mid=(l+r)/2; 49 Build(lson,l,mid); 50 Build(rson,mid,r); 51 } 52 void Updata(int id,Line va) 53 { 54 if(a[id].dl>=va.x1&&a[id].dr<=va.x2) 55 { 56 a[id].cov+=va.flag; 57 Get_Len(id); 58 return ; 59 } 60 if(a[lson].dr>=va.x2) 61 Updata(lson,va); 62 else if(a[rson].dl<=va.x1) 63 Updata(rson,va); 64 else 65 { 66 Line tep=va; 67 tep.x2=a[lson].dr; 68 Updata(lson,tep); 69 70 tep=va; 71 tep.x1=a[rson].dl; 72 Updata(rson,tep); 73 } 74 Get_Len(id); 75 } 76 int main() 77 { 78 int Case=0; 79 while(~scanf("%d",&n)&&n) 80 { 81 int t=0; 82 for(int i=1;i<=n;i++) 83 { 84 double x1,y1,x2,y2; 85 scanf("%lf %lf %lf %lf",&x1,&y1,&x2,&y2); 86 t++; 87 line[t].x1=x1; 88 line[t].x2=x2; 89 line[t].flag=1; 90 line[t].y=y1; 91 x[t]=x1; 92 93 t++; 94 line[t].x1=x1; 95 line[t].x2=x2; 96 line[t].flag=-1; 97 line[t].y=y2; 98 x[t]=x2; 99 } 100 sort(x+1,x+1+t); 101 sort(line+1,line+1+t); 102 Build(1,1,t); 103 Updata(1,line[1]); 104 double ans=0; 105 for(int i=2;i<=t;i++) 106 { 107 ans+=a[1].len*(line[i].y-line[i-1].y); 108 Updata(1,line[i]); 109 } 110 printf("Test case #%d\n",++Case); 111 printf("Total explored area: %.2f\n\n",ans);///註意這裏的格式 112 } 113 return 0; 114 }

HDU 1542 -Atlantis(線掃描)