类型:离散化

题目:http://poj.org/problem?id=1151

来源:Mid-Central European Regional Contest 2000

思路【一】:

(1)使用map离散化

(2)对每个矩形进行覆盖操作

(3)统计覆盖的区域面积和

//poj 1151 Atlantis
// wa ac 312K 32MS
#include <iostream>
#include <map>
#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;const int MAXM = 2610;
int n, cntx, cnty, cas = 1;
bool endd[210][210];
double dax[MAXM], day[MAXM];
map<double, int> mpx, mpy, mpxx, mpyy;
map<double, int>::iterator it;
struct pot {double x1, y1, x2, y2;
}p[MAXM];void solve() {int i, j, k;cntx = cnty = 1;for(it = mpxx.begin(); it != mpxx.end(); ++it)mpx[it->first] = cntx, dax[cntx++] = it->first;for(it = mpyy.begin(); it != mpyy.end(); ++it)mpy[it->first] = cnty, day[cnty++] = it->first;for(i = 1; i <= n; ++i) {int x1 = mpx[p[i].x1];int y1 = mpy[p[i].y1];int x2 = mpx[p[i].x2];int y2 = mpy[p[i].y2];for(j = x1; j < x2; ++j)for(k = y1; k < y2; ++k)endd[j][k] = true;}double sum = 0.0;for(i = 1; i < cntx - 1; ++i)for(j = 1; j < cnty - 1; ++j)if(endd[i][j]) {sum += (dax[i + 1] - dax[i]) * (day[j + 1] - day[j]);}printf("Test case #%d\n", cas++);printf("Total explored area: %.2lf\n\n", sum);
}int main() {double x1, x2, y1, y2;int i;while(scanf("%d", &n) != EOF, n) {cntx = cnty = 1;mpx.clear();mpy.clear();mpxx.clear();mpyy.clear();memset(endd, false, sizeof(endd));for(i = 1; i <= n; ++i) {scanf("%lf %lf %lf %lf", &x1, &y1, &x2, &y2);p[i].x1 = x1, p[i].x2 = x2, p[i].y1 = y1, p[i].y2 = y2;if(mpxx.count(x1) == 0)mpxx[x1] = cntx;if(mpyy.count(y1) == 0)mpyy[y1] = cnty;if(mpxx.count(x2) == 0)mpxx[x2] = cntx;if(mpyy.count(y2) == 0)mpyy[y2] = cnty;}solve();}return 0;
}

思路【二】:

(1)对y坐标离散化,对x坐标建立扫描线

(2)以y坐标建立线段树

(3)插入线段【x扫描线】,每插入一次,统计可得到的矩形面积

(4)对于每条线段,如果有p[t].c > 0 即可统计,当p[t].c = 0时该块矩形扫描完成,不再进行统计

//poj 1151 Atlantis
//ac 224K 0MS
#include <iostream>
#include <sstream>
#include <string>
#include <queue>
#include <stack>
#include <map>
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
using namespace std;#define FOR(i,a,b) for(i = (a); i < (b); ++i)
#define FORE(i,a,b) for(i = (a); i <= (b); ++i)
#define FORD(i,a,b) for(i = (a); i > (b); --i)
#define FORDE(i,a,b) for(i = (a); i >= (b); --i)const int MAXN = 1010;int n, m, len, t = 1;
struct node {int l, r, c;double len, sum;
}p[MAXN * 5];
struct line {double x, y1, y2;int sign;
}l[MAXN];
double Y[MAXN];void creat(int t, int l, int r) {int mid = (l + r) >> 1;p[t].l = l, p[t].r = r;p[t].c = 0, p[t].sum = 0;p[t].len = Y[r] - Y[l];if(l + 1 < r) {creat(t * 2, l, mid);creat(t * 2 + 1, mid, r);return;}
}void insert(int t, int l, int  r, int flag) {int mid = (p[t].l + p[t].r) / 2;if(p[t].l == l && p[t].r == r) {(flag == true) ? ++p[t].c : --p[t].c;}else {if(r <= mid)insert(t * 2, l, r, flag);else if(l >= mid)insert(t * 2 + 1, l, r, flag);else {insert(t * 2, l, mid, flag);insert(t * 2 + 1, mid, r, flag);}}if(p[t].c > 0)p[t].sum = p[t].len;else if(p[t].r - p[t].l > 1)p[t].sum = p[t * 2].sum + p[t * 2 + 1].sum;else // !!!p[t].sum = 0;
}int cmp(line a, line b) {return a.x < b.x;
}int find(double key) {int l = 0, r = len - 1, mid;while(l <= r) {mid = (l + r) >> 1;if(Y[mid] >= key)r = mid - 1;elsel = mid + 1;}return l;
}void solve() {int i;double x1, x2, y1, y2, ans = 0;m = 0;FORE(i, 1, n) {scanf("%lf %lf %lf %lf", &x1, &y1, &x2, &y2);Y[m] = y1; l[m].x = x1; l[m].y1 = y1; l[m].y2 = y2; l[m++].sign = 1;Y[m] = y2; l[m].x = x2; l[m].y1 = y1; l[m].y2 = y2; l[m++].sign = 0;}sort(Y, Y + m);sort(l, l + m, cmp);len = unique(Y, Y + m) - Y;creat(1, 0, len - 1);FOR(i, 0, m) {if(l[i].sign)insert(1, find(l[i].y1), find(l[i].y2), 1);elseinsert(1, find(l[i].y1), find(l[i].y2), 0);ans += p[1].sum * (l[i + 1].x - l[i].x);}printf("Test case #%d\n", t++);printf("Total explored area: %.2lf\n\n", ans);
}int main() {while(scanf("%d", &n) != EOF, n) {solve();}return 0;
}
/*
2
10 10 20 20
15 15 25 25.5
0
*/

poj 1151 Atlantis相关推荐

  1. POJ 1151 Atlantis 矩形面积求交/线段树扫描线

    Atlantis 题目连接 http://poj.org/problem?id=1151 Description here are several ancient Greek texts that c ...

  2. POJ 1151 Atlantis 线段树+扫描线

    解题思路: 先将y轴进行离散化.n个矩形的2n个横边纵坐标共构成最多2n-1个区间的边界,对这些区间编号,建立起线段树. x轴记录左边和右边,左边时是矩形面积增加,覆盖层数增加边,右边是形面积减少,覆 ...

  3. 扫描线三巨头 hdu1928hdu 1255 hdu 1542 [POJ 1151]

    学习链接:http://blog.csdn.net/lwt36/article/details/48908031 学习扫描线主要学习的是一种扫描的思想,后期可以求解很多问题. 扫描线求矩形周长并 hd ...

  4. 【POJ 1151】Atlantis

    [原题题面]传送门 [题面大意] 给出N个矩形,求矩形的面积并. [题解思路] 线段树扫描线入门题. 实现的一些细节: 存边的信息用结构体,根据x的大小排序 从每段的y值的开始操作 线段树维护的是段的 ...

  5. poj 1151(线段树求面积并)

    解题思路:线段树求面积并,水题 #include<iostream> #include<cstdio> #include<cstring> #include< ...

  6. POJ 1151 扫描线 线段树

    题意:给定平面直角坐标系中的N个矩形,求它们的面积并. 题解:建立一个四元组(x,y1,y2,k).(假设y1<y2)用来储存每一条线,将每一条线按x坐标排序.记录所有的y坐标以后排序离散化.离 ...

  7. POJ 1151 线段树+扫描线

    题意:求矩形面积的并 思路: 注意是[l,mid][mid,r] 这是真正的线段了 就当扫描线模板使吧~ //By SiriusRen #include <cmath> #include ...

  8. poj 1151 hdu 1542

    题目概述 给定N个矩形左下角和右上角顶点的坐标,求其面积并 矩形的边一定与坐标轴平行或垂直 时限 1000ms/3000ms 输入 第一行正整数N,其后N行,每行四个浮点数,代表两个顶点的坐标,输入到 ...

  9. POJ 计算几何入门题目推荐

      其实也谈不上推荐,只是自己做过的题目而已,甚至有的题目尚未AC,让在挣扎中.之所以推荐计算几何题,是因为,本人感觉ACM各种算法中计算几何算是比较实际的算法,在很多领域有着重要的用途(例如本人的专 ...

最新文章

  1. 让ASPX和ASMX脱离IIS运行的例子(ASP.NET宿主程序)
  2. [更正]谈获取当前系统类型(SP OR PPC)
  3. C#将内容导出到Word到指定模板
  4. docker 容器启动顺序_Docker容器启动时初始化Mysql数据库
  5. 用计算机模拟地球诞生,计算机模拟显示早期金星或像地球一样宜居
  6. 新政重塑教育格局——中国教育发展报告2021
  7. 国潮国粹剪纸风京剧人物PSD素材,让东方韵味更浓
  8. community 计算模块度_聚苯乙烯泡沫模块可以用在哪些建筑上?
  9. 海龟交易法则02_揭秘海龟思维
  10. VScode单步跟踪Nginx(虚拟机中搭建Nginx)源码
  11. 【Python实例第30讲】F检验与互信息
  12. 冯诺依曼计算机流程图,基本流程图综述
  13. MongoDB和Compass安装教程
  14. jsp技术过时了吗?
  15. 空气质量(air quality) 简称:AQI 计算AQI等笔记
  16. 别让那些贩卖焦虑的人,打扰到你的人生
  17. 智能机器人编程有必要学吗?
  18. 区块链技术与第四次工业革命之于人类的意义
  19. 舵机速度控制原理细解
  20. Java中多线程、多线程的实现方式、同步代码块的方式

热门文章

  1. Wolfram|Alpha Notebook Edition中文快速入门指南(可下载)
  2. To_Heart—题解——[HEOI2013]ALO
  3. Java Selenium防止被网站检测
  4. RedisTemplate下Redis分布式锁引发的系列问题
  5. Experiment 3. Stack and Queue
  6. 张向宁:窄告将让中国营销成本下降10倍
  7. ERROR Error: command failed: yarn
  8. 【TensorFlow实战笔记】卷积神经网络CNN实战-cifar10数据集(tensorboard可视化)
  9. 174.127.195.176/bbs/index.php,[原创]一次逆向fb寻找密码的记录及还原相关算法
  10. 【输出N行杨辉三角形】两种输出方式(直角三角形型和等腰三角形型)C语言