A
来源:互联网 发布:游族网络大皇帝礼包 编辑:程序博客网 时间:2024/06/10 12:12
题意
给定多个矩形,会出现重叠的情况,问总面积是多少?
解法
采用了线段树+扫描线的做法,
一些小技巧
- 离散化: 先用sort进行需要离散的数据排须,然后用unique进行去重复。
unique()函数的参数和sort函数一致,将重复的元素放到数组的最后面,返回值是最后一个unique的数地址+1。 - 这里面有个很莫名其妙的部分就是update的时候r要先减1,之后在进行区间长度计算的时候r再加回来,如果不进行这样的处理,会出现没法计算区间长度的情况。
#include <iostream>#include <cstdio>#include <cmath>#include <algorithm>#include <cstring>using namespace std;const int maxn = 100 + 10;struct segment{ double l, r, h; int f;}segments[2 * maxn];int n, sn, pos_num, coverv[2 * 4 * maxn];double pos[2 * maxn],lenv[2 * 4 * maxn];int cmp(segment a, segment b){ if(a.h < b.h) return 1; else return 0;}void maintain(int o, int L, int R){ if(coverv[o]) lenv[o] = pos[R + 1] - pos[L]; else if(L == R){ lenv[o] = 0; } else lenv[o] = lenv[o << 1] + lenv[o << 1 | 1];}void update(int o, int l, int r, int L, int R, int v){ if(l <= L && r >= R){ coverv[o] += v; } else{ int M = L + (R - L) / 2; if(l <= M) update(o << 1, l, r, L, M, v); if(r > M) update(o << 1 | 1, l, r, M + 1, R, v); } maintain(o, L, R);}int main(){ //freopen("input.txt", "r", stdin); int t = 0; while(scanf("%d", &n) != EOF){ if(n == 0) break; t ++; printf("Test case #%d\n", t); printf("Total explored area: "); memset(pos, 0, sizeof(pos)); memset(coverv, 0, sizeof(coverv)); memset(lenv, 0, sizeof(lenv)); sn = 0; pos_num = 0; for(int i = 1; i <= n; i++){ double x1, y1, x2, y2; scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2); segments[sn].l = x1; segments[sn].r = x2; segments[sn].h = y1; segments[sn].f = 1; sn ++; segments[sn].l = x1; segments[sn].r = x2; segments[sn].h = y2; segments[sn].f = -1; sn ++; pos[pos_num++] = x1; pos[pos_num++] = x2; } sort(pos, pos + pos_num); sort(segments, segments + sn, cmp); pos_num = unique(pos, pos + pos_num) - pos; //cout << pos_num <<endl; double ans = 0; for(int i = 0; i < sn; i++){ int l = lower_bound(pos, pos + pos_num, segments[i].l) - pos; int r = lower_bound(pos, pos + pos_num, segments[i].r) - pos -1; //cout << l << r << endl; update(1, l, r, 0, pos_num - 1, segments[i].f); //cout << lenv[1] <<"("<< lenv[2] <<","<<lenv[3]<<")" << " " << (segments[i+1].h - segments[i].h) << endl; ans += lenv[1] * (segments[i+1].h - segments[i].h); } printf("%.2lf\n\n", ans); } return 0;}
阅读全文
0 0
- a
- a
- a
- a
- a
- a
- a
- a
- a
- a
- a
- a
- a
- A
- A*
- a
- A
- a
- CUHK(SZ)机器学习班
- 【HTML5学习笔记】25:CSS表格和列表
- 开启人生新篇章
- 百万数据查询优化技巧三十则
- 协议森林02 小喇叭开始广播 (以太网与WiFi协议)
- A
- 【学生】实时错误3021
- 获取运行Oracle实例的用户名
- spring整合mybatis ORA-00911: 无效字符问题解决方式
- UVa Live 7040 (二项式反演+线性求逆元)
- 二叉树平衡检查(递归思想分析)
- Unity 3D 官方文档 UGUI总览 IMGUI OnGUI Editor脚本初窥1
- HTML5基础归纳(3)--定位简述
- Java8 日期和时间实用技巧