アトランティスHDU - 1542(+スキャン線分木)

 

アトランティス

制限時間:1000分の2000 MS(Javaの/その他)メモリの制限:32768分の65536 K(Javaの/その他)
の合計提出(S):23452受理提出(S):9278

問題の説明

伝説的な島アトランティスの記述が含まれているいくつかの古代ギリシャ語のテキストがあります。これらのテキストの一部では、島の一部のマップが含まれています。しかし残念ながら、これらのマップは、アトランティスの異なる領域を記述する。あなたの友人ビルはマップが存在するため、総面積を知っている必要があります。あなたは(愚か)この量を計算するプログラムを書くために志願しました。

入力

The input file consists of several test cases. Each test case starts with a line containing a single integer n (1<=n<=100) of available maps. The n following lines describe one map each. Each of these lines contains four numbers x1;y1;x2;y2 (0<=x1<x2<=100000;0<=y1<y2<=100000), not necessarily integers. The values (x1; y1) and (x2;y2) are the coordinates of the top-left resp. bottom-right corner of the mapped area.

The input file is terminated by a line containing a single 0. Don’t process it.

Output

For each test case, your program should output one section. The first line of each section must be “Test case #k”, where k is the number of the test case (starting with 1). The second one must be “Total explored area: a”, where a is the total explored area (i.e. the area of the union of all rectangles in this test case), printed exact to two digits to the right of the decimal point.

Output a blank line after each test case.

Sample Input

2 10 10 20 20 15 15 25 25.5 0

Sample Output

Test case #1

Total explored area: 180.00

分析:模板题

代码:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int maxn = 110;
 4 
 5 struct edge
 6 {
 7     double l, r;
 8     double h;
 9     int pos;
10     bool operator < (const edge &a)const
11     {
12         return h < a.h;
13     }
14 }e[maxn << 1];
15 
16 struct node
17 {
18     int l, r;
19     double sum;
20     int flag;
21 }t[maxn << 3];
22 int n;
23 double x[maxn << 1];
24 
25 void pushup(int tar)
26 {
27     if (t[tar].flag) t[tar].sum = x[t[tar].r + 1] - x[t[tar].l];
28     else if (t[tar].l == t[tar].r) t[tar].sum = 0;
29     else t[tar].sum = t[tar << 1].sum + t[tar << 1 | 1].sum;
30 }
31 
32 void build(int l, int r, int tar)
33 {
34     t[tar].l = l, t[tar].r = r, t[tar].sum = 0, t[tar].flag = 0;
35     if (l == r) return;
36     int mid = (l + r) >> 1;
37     build(l, mid, tar << 1);
38     build(mid + 1, r, tar << 1 | 1);
39 }
40 
41 void update(int l, int r, int v, int tar)
42 {
43     if (l == t[tar].l && r == t[tar].r)
44     {
45         t[tar].flag += v;
46         pushup(tar);
47         return;
48     }
49     int mid = (t[tar].l + t[tar].r) >> 1;
50     if (r <= mid) update(l, r, v, tar << 1);
51     else if (l > mid) update(l, r, v, tar << 1 | 1);
52     else update(l, mid, v, tar << 1), update(mid + 1, r, v, tar << 1 | 1);
53     pushup(tar);
54 }
55 
56 int main()
57 {
58     int num, cnt;
59     double x1, y1, x2, y2;
60     int cases = 0;
61 
62     while (cin >> n && n)
63     {
64         num = cnt = 0;
65         for (int i = 1; i <= n; i++)
66         {
67             scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);
68             e[++num].l = x1, e[num].r = x2, e[num].h = y1, e[num].pos = -1;
69             e[++num].l = x1, e[num].r = x2, e[num].h = y2, e[num].pos = 1;
70             x[++cnt] = x1, x[++cnt] = x2;
71         }
72         sort(e + 1, e + 1 + num);
73         sort(x + 1, x + 1 + cnt);
74         int tot = unique(x + 1, x + 1 + cnt) - (x + 1);
75         //cout << tot << endl;
76         build(1, tot, 1);
77         double ans = 0;
78         for (int i = 1; i <= num; i++)
79         {
80             int l = lower_bound(x + 1, x + 1 + tot, e[i].l) - x;
81             int r = lower_bound(x + 1, x + 1 + tot, e[i].r) - x - 1;
82             //cout << l << " " << r << endl;
83             update(l, r, e[i].pos, 1);
84             ans += (e[i + 1].h - e[i].h) * t[1].sum;
85         }
86         printf("Test case #%d\nTotal explored area: %.2f\n\n", ++cases, ans);
87     }
88 }

 

おすすめ

転載: www.cnblogs.com/liuwenhan/p/11369048.html