poj 1151 Atlantis
类型:离散化
题目: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相关推荐
- POJ 1151 Atlantis 矩形面积求交/线段树扫描线
Atlantis 题目连接 http://poj.org/problem?id=1151 Description here are several ancient Greek texts that c ...
- POJ 1151 Atlantis 线段树+扫描线
解题思路: 先将y轴进行离散化.n个矩形的2n个横边纵坐标共构成最多2n-1个区间的边界,对这些区间编号,建立起线段树. x轴记录左边和右边,左边时是矩形面积增加,覆盖层数增加边,右边是形面积减少,覆 ...
- 扫描线三巨头 hdu1928hdu 1255 hdu 1542 [POJ 1151]
学习链接:http://blog.csdn.net/lwt36/article/details/48908031 学习扫描线主要学习的是一种扫描的思想,后期可以求解很多问题. 扫描线求矩形周长并 hd ...
- 【POJ 1151】Atlantis
[原题题面]传送门 [题面大意] 给出N个矩形,求矩形的面积并. [题解思路] 线段树扫描线入门题. 实现的一些细节: 存边的信息用结构体,根据x的大小排序 从每段的y值的开始操作 线段树维护的是段的 ...
- poj 1151(线段树求面积并)
解题思路:线段树求面积并,水题 #include<iostream> #include<cstdio> #include<cstring> #include< ...
- POJ 1151 扫描线 线段树
题意:给定平面直角坐标系中的N个矩形,求它们的面积并. 题解:建立一个四元组(x,y1,y2,k).(假设y1<y2)用来储存每一条线,将每一条线按x坐标排序.记录所有的y坐标以后排序离散化.离 ...
- POJ 1151 线段树+扫描线
题意:求矩形面积的并 思路: 注意是[l,mid][mid,r] 这是真正的线段了 就当扫描线模板使吧~ //By SiriusRen #include <cmath> #include ...
- poj 1151 hdu 1542
题目概述 给定N个矩形左下角和右上角顶点的坐标,求其面积并 矩形的边一定与坐标轴平行或垂直 时限 1000ms/3000ms 输入 第一行正整数N,其后N行,每行四个浮点数,代表两个顶点的坐标,输入到 ...
- POJ 计算几何入门题目推荐
其实也谈不上推荐,只是自己做过的题目而已,甚至有的题目尚未AC,让在挣扎中.之所以推荐计算几何题,是因为,本人感觉ACM各种算法中计算几何算是比较实际的算法,在很多领域有着重要的用途(例如本人的专 ...
最新文章
- 让ASPX和ASMX脱离IIS运行的例子(ASP.NET宿主程序)
- [更正]谈获取当前系统类型(SP OR PPC)
- C#将内容导出到Word到指定模板
- docker 容器启动顺序_Docker容器启动时初始化Mysql数据库
- 用计算机模拟地球诞生,计算机模拟显示早期金星或像地球一样宜居
- 新政重塑教育格局——中国教育发展报告2021
- 国潮国粹剪纸风京剧人物PSD素材,让东方韵味更浓
- community 计算模块度_聚苯乙烯泡沫模块可以用在哪些建筑上?
- 海龟交易法则02_揭秘海龟思维
- VScode单步跟踪Nginx(虚拟机中搭建Nginx)源码
- 【Python实例第30讲】F检验与互信息
- 冯诺依曼计算机流程图,基本流程图综述
- MongoDB和Compass安装教程
- jsp技术过时了吗?
- 空气质量(air quality) 简称:AQI 计算AQI等笔记
- 别让那些贩卖焦虑的人,打扰到你的人生
- 智能机器人编程有必要学吗?
- 区块链技术与第四次工业革命之于人类的意义
- 舵机速度控制原理细解
- Java中多线程、多线程的实现方式、同步代码块的方式
热门文章
- Wolfram|Alpha Notebook Edition中文快速入门指南(可下载)
- To_Heart—题解——[HEOI2013]ALO
- Java Selenium防止被网站检测
- RedisTemplate下Redis分布式锁引发的系列问题
- Experiment 3. Stack and Queue
- 张向宁:窄告将让中国营销成本下降10倍
- ERROR Error: command failed: yarn
- 【TensorFlow实战笔记】卷积神经网络CNN实战-cifar10数据集(tensorboard可视化)
- 174.127.195.176/bbs/index.php,[原创]一次逆向fb寻找密码的记录及还原相关算法
- 【输出N行杨辉三角形】两种输出方式(直角三角形型和等腰三角形型)C语言