[codevs3044][POJ1151]矩形面积求并
[codevs3044][POJ1151]矩形面积求并
试题描述
输入n个矩形,求他们总共占地面积(也就是求一下面积的并)
输入
可能有多组数据,读到n=0为止(不超过15组)
每组数据第一行一个数n,表示矩形个数(n<=100)
接下来n行每行4个实数x1,y1,x2,y1(0 <= x1 < x2 <= 100000;0 <= y1 < y2 <= 100000),表示矩形的左下角坐标和右上角坐标
输出
每组数据输出一行表示答案
输入示例
2 10 10 20 20 15 15 25 25.5 0
输出示例
180.00
数据规模及约定
见“输入”
题解
扫描线 + 线段树。
线段树标记永久化,因为这题每个时刻只需要知道线段树根节点的信息,而不是每次查询一段区间,所以很容易实现,具体见代码,或者黄学长的题解。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | #include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cctype> #include <algorithm> #include <cmath> using namespace std; int read() { int x = 0, f = 1; char c = getchar(); while (!isdigit(c)){ if (c == '-' ) f = -1; c = getchar(); } while (isdigit(c)){ x = x * 10 + c - '0' ; c = getchar(); } return x * f; } #define maxn 110 struct Line { int l, r, h, tp; Line() {} Line( int _1, int _2, int _3, int _4): l(_1), r(_2), h(_3), tp(_4) {} bool operator < ( const Line& t) const { return h < t.h; } } ls[maxn<<1]; double posx[maxn<<1], posy[maxn<<1], numx[maxn<<1], numy[maxn<<1], ans; int cntv[maxn<<3]; double sumv[maxn<<3]; void maintain( int L, int R, int o) { int lc = o << 1, rc = lc | 1; if (cntv[o]) sumv[o] = numx[R] - numx[L-1]; else if (L == R) sumv[o] = 0; else sumv[o] = sumv[lc] + sumv[rc]; return ; } void update( int L, int R, int o, int ql, int qr, int v) { if (ql <= L && R <= qr) { cntv[o] += v; return maintain(L, R, o); } int M = L + R >> 1, lc = o << 1, rc = lc | 1; if (ql <= M) update(L, M, lc, ql, qr, v); if (qr > M) update(M+1, R, rc, ql, qr, v); return maintain(L, R, o); } int main() { while (1) { int n = read(), cntx = 0, cnty = 0, cntl = 0; if (!n) break ; for ( int i = 1; i <= n; i++) { double x1, x2, y1, y2; scanf( "%lf%lf%lf%lf" , &x1, &y1, &x2, &y2); posx[++cntx] = x1; posx[++cntx] = x2; posy[++cnty] = y1; posy[++cnty] = y2; numx[cntx-1] = posx[cntx-1]; numx[cntx] = posx[cntx]; numy[cnty-1] = posy[cnty-1]; numy[cnty] = posy[cnty]; } sort(numx + 1, numx + cntx + 1); sort(numy + 1, numy + cnty + 1); for ( int i = 1; i <= n; i++) { int x1, x2, y1, y2; x1 = lower_bound(numx + 1, numx + cntx + 1, posx[(i<<1)-1]) - numx; x2 = lower_bound(numx + 1, numx + cntx + 1, posx[i<<1]) - numx; y1 = lower_bound(numy + 1, numy + cnty + 1, posy[(i<<1)-1]) - numy; y2 = lower_bound(numy + 1, numy + cnty + 1, posy[i<<1]) - numy; ls[++cntl] = Line(x1, x2, y1, 1); ls[++cntl] = Line(x1, x2, y2, -1); } sort(ls + 1, ls + cntl + 1); memset(cntv, 0, sizeof (cntv)); memset(sumv, 0, sizeof (sumv)); ans = 0; double start = numx[1]; for ( int i = 1; i < cntx; i++) numx[i] = numx[i+1] - start; for ( int i = 1; i < cntl; i++) { if (ls[i].l < ls[i].r) update(1, cntx - 1, 1, ls[i].l, ls[i].r - 1, ls[i].tp); ans += (numy[ls[i+1].h] - numy[ls[i].h]) * sumv[1]; } printf( "%.2lf\n" , ans); } return 0; } |
注意:POJ 上输出格式不太一样,详见题面。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步