Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 16222 | Accepted: 6172 |
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
思路:首先将横坐标离散化,再对纵坐标排序,然后根据y轴从下往上扫描,每次的高度就是seg[i].y-seg[i-1].y,这就相当于分矩形的宽,然后要做的事就是查询x轴(矩形长)的有效长度,这就要交给线段树了。
AC代码:
1 /************************************************************************* 2 > File Name: area.cpp 3 > Author: wangzhili 4 > Mail: wangstdio.h@gmail.com 5 > Created Time: 2014/3/1 星期六 16:06:57 6 ************************************************************************/ 7 8 #include<iostream> 9 #include<algorithm> 10 #include<cstdio> 11 #define MAX 1000 12 using namespace std; 13 class TreeNode 14 { 15 public: 16 int left; 17 int right; 18 int mid; 19 int cover; 20 int flag; 21 double length; 22 }; 23 typedef struct 24 { 25 double xl, xr, y; 26 int flag; 27 }Line; 28 TreeNode node[3*MAX]; 29 Line seg[MAX]; 30 double x[MAX]; 31 double length; 32 bool cmp(Line a, Line b) 33 { 34 return a.y < b.y; 35 } 36 37 void BuildTree(int k, int l, int r) 38 { 39 node[k].left = l; 40 node[k].right = r; 41 node[k].mid = (l + r) >> 1; 42 node[k].cover = 0; 43 node[k].flag = 0; 44 if(l + 1 == r) 45 { 46 node[k].flag = 1; 47 return ; 48 } 49 int mid = (l + r) >> 1; 50 BuildTree(k << 1, l, mid); 51 BuildTree(k << 1|1, mid, r); 52 } 53 54 void UpdateTree(int k, int l, int r, int flag) 55 { 56 if(node[k].left == l && node[k].right == r) 57 { 58 node[k].cover += flag; 59 node[k].length = x[r-1] - x[l-1]; 60 return ; 61 } 62 if(node[k].flag) 63 return ; 64 if(node[k].mid <= l) 65 UpdateTree(k << 1|1, l, r, flag); 66 else if(node[k].mid >= r) 67 UpdateTree(k << 1, l, r, flag); 68 else 69 { 70 UpdateTree(k << 1, l, node[k].mid, flag); 71 UpdateTree(k << 1|1, node[k].mid, r, flag); 72 } 73 } 74 75 void GetLength(int k) 76 { 77 if(node[k].cover > 0) 78 { 79 length += node[k].length; 80 return ; 81 } 82 if(node[k].flag) 83 return; 84 GetLength(k << 1); 85 GetLength(k << 1|1); 86 } 87 88 int GetIndex(double num, int length) 89 { 90 int l, r, mid; 91 l = 0, r = length-1; 92 while(l <= r) 93 { 94 mid = (l + r) >> 1; 95 if(x[mid] == num) 96 return mid; 97 else if(x[mid] > num) 98 r = mid - 1; 99 else 100 l = mid + 1; 101 } 102 } 103 104 int main(int argc, char const *argv[]) 105 { 106 int n, i, j, k, cnt; 107 int xl, xr; 108 double ans; 109 double x1, y1, x2, y2; 110 cnt = 0; 111 BuildTree(1, 1, 205); 112 // freopen("in.c", "r", stdin); 113 while(~scanf("%d", &n) && n) 114 { 115 j = 0; 116 ans = 0.; 117 for(i = 1; i < 408; i ++) 118 { 119 node[i].cover = 0; 120 } 121 for(i = 0; i < n; i ++) 122 { 123 scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2); 124 seg[j].xl = x1; 125 seg[j].xr = x2; 126 seg[j].y = y1; 127 x[j] = x1; 128 seg[j ++].flag = 1; 129 seg[j].xl = x1; 130 seg[j].xr = x2; 131 seg[j].y = y2; 132 x[j] = x2; 133 seg[j ++].flag = -1; 134 } 135 sort(x, x+j); 136 sort(seg, seg+j, cmp); 137 k = 1; 138 for(i = 1; i < j; i ++) 139 { 140 if(x[i] != x[i-1]) 141 x[k ++] = x[i]; 142 } 143 xl = GetIndex(seg[0].xl, k) + 1; 144 xr = GetIndex(seg[0].xr, k) + 1; 145 UpdateTree(1, xl, xr, seg[0].flag); 146 length = 0; 147 GetLength(1); 148 for(i = 1; i < j; i ++) 149 { 150 ans += (seg[i].y-seg[i-1].y)*length; 151 xl = GetIndex(seg[i].xl, k)+1; 152 xr = GetIndex(seg[i].xr, k)+1; 153 UpdateTree(1, xl, xr, seg[i].flag); 154 length = 0.; 155 GetLength(1); 156 } 157 printf("Test case #%d\nTotal explored area: %.2lf\n\n", ++cnt, ans); 158 } 159 return 0; 160 }
原文:http://www.cnblogs.com/anhuizhiye/p/3575398.html