[HNOI2012]三角形覆盖问题
2014-01-29 21:11
162 查看
#include<cmath> #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<iostream> using namespace std; class Dread{ private: bool isdigit(char ch) { return ch >= '0' && ch <= '9'; } bool isalpha(char ch) { return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'); } void Getchar(int &tmp){ char ch; tmp = 0; bool b = true; while (ch = getchar()){ if (ch == '-') b = false; if (isdigit(ch)) break; } for (; isdigit(ch); ch = getchar()) tmp = tmp * 10 + ch - '0'; if (!b) tmp = -tmp; } void Getchar(char &tmp){ while (tmp = getchar()) if (isalpha(tmp)) break; } public: int Int(){ int x; Getchar(x); return x; } char Ch(){ char x; Getchar(x); return x; } }Read; const int maxn = 101111; const int maxm = 1010000; struct zy{ int x, y, d, l, r; bool operator < (const zy a) const { return y < a.y; } bool operator > (const zy b) const { return l <= b.l && b.r <= r; } }a[maxn]; int q[maxn]; int sum[maxm], n; int next[maxn], last[maxn]; bool b[maxn]; int maxh = 0; void init(){ n = Read.Int(); for (int i = 1; i <= n; i ++){ a[i].x = Read.Int(), a[i].y = Read.Int(), a[i].d = Read.Int(); a[i].l = a[i].x, a[i].r = a[i].x + a[i].d; next[i] = i + 1, last[i] = i - 1; maxh = max(maxh, a[i].d + a[i].y); } } int head; void Delete(int j){ if (j == head) head = next[j]; last[next[j]] = last[j]; next[last[j]] = next[j]; b[j] = false; } void work(){ sort(a + 1, a + n + 1); memset(b, 1, sizeof(b)); double len = 0; head = 1; for (int i = 1; i <= n && a[i].y == a[1].y; i ++) for (int j = a[i].l; j < a[i].r; j ++){ if (!sum[j]) len ++; sum[j] ++; } double ans = 0; for (int i = a[1].y + 1; i <= maxh; i ++){ double lastlen = len; int ww = 0; for (int j = head; a[j].y < i && j <= n; j = next[j]){ a[j].r --; if (a[j].r < a[j].x) Delete(j); else { sum[a[j].r] --; if (!sum[a[j].r]) len --; q[++ww] = j; } } ans += (lastlen + len) * 1.0 / 2.0; for (int j = head; a[j].y <= i && j <= n; j = next[j]) if (a[j].y == i){ int k; for (k = 1; k <= ww; k ++){ if (!b[q[k]]) continue; if (a[q[k]] > a[j]){ Delete(j); break; } if (a[j] > a[q[k]]){ Delete(q[k]); for (int kk = a[q[k]].l; kk < a[q[k]].r; kk ++){ sum[kk] --; if (!sum[kk]) len --; } } } if (k <= ww) continue; for (int kk = a[j].l; kk < a[j].r; kk ++){ if (!sum[kk]) len ++; sum[kk] ++; } } } printf("%.1lf\n", ans); } int main(){ init(); work(); return 0; }
2731: [HNOI2012]三角形覆盖问题
Time Limit: 20 Sec Memory Limit: 128 MB
Submit: 172 Solved: 95
[Submit][Status]
Description
[align=left]二维平面中,给定 N个等腰直角三角形(每个三角形的两条直角边分别[/align][align=left]平行于坐标轴,斜边从左上到右下)。我们用三个非负整数( x, y, d)来描[/align]
[align=left]述这样一个三角形,三角形三个顶点的坐标[/align]
[align=left] [/align]
分别为(x, y), (x + d, y)和(x,y +
d)。要求计算这 N个三角形所覆盖的总面
[align=left]积。例如,下图有 3 个三角形,覆盖的总面积为 11.0。[/align]
Input
输入文件第一行为一个正整数N,表示三角形的个数。接下来的N行每行有用空格隔开的三个非负整数, x,y ,
d,描述一个三角
形的顶点坐标,分别为
( x, y), (x+
d, y), ( x,y+d),
其中 x, y,d
满足0≤ x, y,
d≤1000000。
对于50%的数据,1≤ N≤500;
100%的数据,1≤N≤10000。
Output
仅包含一行,为一个实数 S ,表示所有三角形所覆盖的总面积,输出恰好保留一位小数。输入数据保证 S≤2^31。
Sample Input
3 .1 1 4
2 0 2
3 2 2
Sample Output
11.0HINT
Source
day2从最低点弄根扫描线,一直到最高点,每次扫描线++
两根扫描之间的面积,就是下面那根扫描线被覆盖的长度+上面那根扫描线被非底边覆盖的长度,然后除以2。
然后最坏是100000 * 1000000
直接上代码
相关文章推荐
- BZOJ 2731: [HNOI2012]三角形覆盖问题
- [BZOJ 2731][HNOI 2012]三角形覆盖问题(计算几何+扫描线暴力)
- 【bzoj2731】[HNOI2012]三角形覆盖问题
- BZOJ 2731: [HNOI2012]三角形覆盖问题
- [HNOI2012]三角形覆盖问题
- [HNOI 2012]三角形覆盖问题
- [BZOJ 2727][HNOI 2012]双十字(树状数组+计数问题)
- [BZOJ 2730][HNOI 2012]矿场搭建(Tarjan求割点与桥+计数问题)
- [BZOJ 2728][HNOI 2012]与非(并查集+计数问题)
- [省选前题目整理][BZOJ 2730][HNOI 2012]矿场搭建(Tarjan求割点+计数问题)
- 深析静态链接库和动态链接库相同函数覆盖及库调用顺序问题
- POJ 3261 字符串上的k次覆盖问题
- codility上的问题(15) Xi 2012
- android 通知覆盖以及PendingIntent参数问题
- bzoj 2734: [HNOI2012]集合选数
- 辛星跟您解析在CSS面包屑中三角形的定位问题
- UVA 10382 - Watering Grass【贪心+区间覆盖问题+高精度】
- 最小权顶点覆盖问题
- mysql索引覆盖之innodb和myisam效率问题
- VS2010/VS2012 重新编译问题