codeforces 70D Professor's task(动态二维凸包)
题目链接:http://codeforces.com/contest/70/problem/D
Once a walrus professor Plato asked his programming students to perform the following practical task.
The students had to implement such a data structure that would support a convex hull on some set of points S. The input to the program had q queries of two types:
1. Add a point with coordinates (x, y) into the set S. Note that in this case the convex hull of S could have changed, and could have remained the same.
2. Say whether a point with coordinates (x, y) belongs to an area limited by the convex hull, including the border.
All the students coped with the task. What about you?
The first line contains an integer q (4 ≤ q ≤ 105).
Then follow q lines in the following way: "t x y", where t is the query type (1 or 2), and (x, y) are the coordinates of the point ( - 106 ≤ x, y ≤ 106, x and y are integers).
There is at least one query of type 2.
It is guaranteed that the three queries of the first type follow first and the points given in the queries form a non-degenerative triangle. Also all the points added in S are distinct.
For each query of the second type print one string containing "YES", if the point lies inside the convex hull or on its border. Otherwise, print "NO".
题目大意:q个操作。操作1:往点集中添加一个点。操作2:给一个点,问这个点是否在点集所构成的凸包内部(包括边缘)。
思路:增量法求动态凸包。可以看:http://blog.csdn.net/crazy_ac/article/details/8499443
PS:原来map的迭代器是首尾相连的……
代码(156MS):
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <map>
using namespace std;
typedef long long LL;
typedef map<int, int> MPII; struct Point {
int x, y;
Point() {}
Point(int x, int y): x(x), y(y) {}
Point(MPII::iterator it): x(it->first), y(it->second) {}
Point operator - (const Point &rhs) const {
return Point(x - rhs.x, y - rhs.y);
}
}; LL cross(const Point &a, const Point &b) {
return (LL)a.x * b.y - (LL)a.y * b.x;
} LL cross(const Point &o, const Point &a, const Point &b) {
return cross(a - o, b - o);
} bool below(MPII &mp, Point p) {
if(mp.empty()) return false;
if(p.x < mp.begin()->first || mp.rbegin()->first < p.x) return false;
MPII::iterator a = mp.lower_bound(p.x), b = a--;
if(b->first == p.x) return b->second >= p.y;
return cross(a, b, p) <= ;
} void insert(MPII &mp, Point p) {
if(below(mp, p)) return ;
MPII::iterator a, b, it;
mp[p.x] = p.y;
it = mp.lower_bound(p.x); b = it; ++b;
if(b != mp.end()) {
a = b++;
while(b != mp.end() && cross(p, a, b) >= )
mp.erase(a), a = b++;
} a = it; --a;
if(it != mp.begin() && a != mp.begin()) {
b = a--;
while(b != mp.begin() && cross(p, b, a) <= )
mp.erase(b), b = a--;
}
} MPII up, down;
int q, op, x, y; int main() {
scanf("%d", &q);
while(q--) {
scanf("%d%d%d", &op, &x, &y);
if(op == ) {
insert(up, Point(x, y));
insert(down, Point(x, -y));
} else {
puts((below(up, Point(x, y)) && below(down, Point(x, -y))) ? "YES" : "NO");
}
}
}
codeforces 70D Professor's task(动态二维凸包)的更多相关文章
- Codeforces Gym 100286A. Aerodynamics 计算几何 求二维凸包面积
Problem A. AerodynamicsTime Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hust.edu.cn/vjudge/co ...
- C++ 里 构建动态二维数组
//****动态二维数组 /* int m=3; int **data; int n=2; data=new int*[m]; for(int j=0;j<m;j++) { data[j]=ne ...
- C++动态二维数组的创建
两种方式. 一,二级指针,创建2行3列的动态二维数组. 这里,p指向的是2个地址,这两个地址各指向长度为3的一维整型数组. 在内存中,每行元素内部顺序排列.两行元素的首地址不同,p[1]与p[2]存放 ...
- C++建立动态二维数组
C++建立动态二维数组主要有两种方法: 1.使用数组指针,分配一个指针数组,将其首地址保存在b中,然后再为指针数组的每个元素分配一个数组 int * ...
- php 合并图片 (将活动背景图片和动态二维码图片合成一张图片)
<?php //案例一:将活动背景图片和动态二维码图片合成一张图片 //图片一 $path_1 = './background.png'; //图片二 $path_2 = './FU0851_2 ...
- 动态二维数组赋值及for循环遍历和toString遍历
package com.Summer_0421.cn; import java.util.Arrays; /** * @author Summer * 动态二维数组赋值及for循环遍历和toStrin ...
- 以杨辉三角为例,从内存角度简单分析C语言中的动态二维数组
学C语言,一定绕不过指针这一大难关,而指针最让人头疼的就是各种指向关系,一阶的指针还比较容易掌握,但一旦阶数一高,就很容易理不清楚其中的指向关系,现在我将通过杨辉三角为例,我会用四种方法从内存的角度简 ...
- python小工具myqr生成动态二维码
python小工具myqr生成动态二维码 (一)安装 (二)使用 (一)安装 命令: pip install myqr 安装完成后,就可以在命令行中输入 myqr 查看下使用帮助: myqr --he ...
- Python | 一行命令生成动态二维码
当我看到别人的二维码都做的这么炫酷的时候,我心动了! 我也想要一个能够吸引眼球的二维码,今天就带大家一起用 Python 来做一个炫酷的二维码! 首先要安装工具 myqr: pip install m ...
随机推荐
- Hadoop学习笔记(一)
HDFS适合一次写入,多次读取NameNode将文件系统的元数据存储在内存中,因此HDFS所能存储的文件总数受限于NameNode容量类:IOUtil Progressable URL.setURLS ...
- ECharts SSH+JQueryAjax+Json+JSP将数据库中数据填充到ECharts中
本文引用自:http://blog.csdn.net/ArcticFoxHan/article/details/38071641 1.导入包,搭建SSH框架 导入Jquery的JS包,<sc ...
- pomelo架构概览
pomelo之所以简单易用.功能全面,并且具有高可扩展性.可伸缩性等特点,这与它的技术选型和方案设计是密不可分的.在研究大量游戏引擎设计思路基础上,结合以往游戏开发的经验,确定了pomelo框架的设计 ...
- CSS控制"标题前增加小图标或编号"
---题目前加图片--- p:before { content:url(xxx/xx.png); }//所有p的最前都有一个图标 p.a:after { content:url(xxx/xx.png) ...
- QFile文件操作-QT
#include <QCoreApplication> #include<QFile> #include<QString> #include<QDebug&g ...
- 如何解决jQuery Validation针对动态添加的表单无法工作的问题?
为了充分利用ASP.NET MVC在服务端呈现HTML的能力,在<利用动态注入HTML的方式来设计复杂页面>一文中介绍了,通过Ajax调用获取HTML来呈现复杂页面中某一部分界面的解决方案 ...
- 高效的两段式循环缓冲区──BipBuffer
Simon Cooke,美国 (原作者) 北京理工大学 20981 陈罡(翻译) 写在前面的话: 循环缓冲区是一个非常常用的数据存储结构,已经被广泛地用于连续.流数据的存储和通信应用中.对于循环缓冲区 ...
- Magento PDF发票,支持中文,以及修改的办法
Magento PDF发票,支持中文,以及修改的办法. 如果让magento的PDF发票支持中文.Magento生成PDF发票.使用的是zend framework的zend_pdf类. 下面是一 ...
- Swift-11-协议(Protocols)
协议定义了一个蓝图,规定了用来实现某一特定工作或者功能所必须的方法和属性.类.结构体或者枚举类型都可以遵循协议,并提供具体实现来完成协议定义的方法和功能.任意能满足协议要求的类型被称为遵循confor ...
- ASP.NET中身份验证
ASP.NET中身份验证有三种方式:Windows.Forms和Passport. 1.Windows验证,基于窗体验证,需要每个页面写上验证身份代码,相对灵活,但操作过于复杂: 2.Passport ...