• [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

    数据规模及约定

    见“输入

    题解

    扫描线 + 线段树。

    线段树标记永久化,因为这题每个时刻只需要知道线段树根节点的信息,而不是每次查询一段区间,所以很容易实现,具体见代码,或者黄学长的题解

    #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
    ", ans);
    	}
    	
    	return 0;
    }
    

    注意:POJ 上输出格式不太一样,详见题面。

  • 相关阅读:
    数论 UVA 10943
    数论 UVA 11889
    数论 UVA 11388
    UVA 572
    hdu 1016
    poj 1308
    poj 1363
    java web-----servelet
    java IO文件读写例子(OutputStream,InputStream,Writer,Reader)
    java web环境配置类型问题
  • 原文地址:https://www.cnblogs.com/xiao-ju-ruo-xjr/p/6474671.html
Copyright © 2020-2023  润新知