POJ 1228 Grandpa's Estate --深入理解凸包
题意: 判断凸包是否稳定。
解法: 稳定凸包每条边上至少有三个点。
这题就在于求凸包的细节了,求凸包有两种算法:
1.基于水平序的Andrew算法
2.基于极角序的Graham算法
两种算法都有一个类似下面的语句:
for(int i=0;i<n;i++) {
while(m > 1 && Cross(ch[m-1]-ch[m-2], p[i]-ch[m-2]) <= 0) m--;
ch[m++] = p[i];
}
这样的话,求出来就是最简凸包,即点数尽量少的凸包,因为Cross == 0的情况也被出栈了,所以一条凸包边上就会三点共线了。
我们把语句改下,把Cross.. <=0 改成 Cross.. < 0 ,那么求的就是最繁凸包,即可能一条凸包边上包含很多点也属于凸包的点。
即下面的情况:

最简凸包即为蓝色的四个点。 最繁凸包求出的是所有蓝点和红点。
作为这个题,我们怎么求其实都可以:
1.如果求最简凸包,我们只需判断总共有多少个点在该凸包边上即可(端点也算),如果 < 3 ,则不符。
2.如果求的是最繁的凸包,就不能用上面的判法,因为怎么判都只有两个点了,这时候可以采用下面的方法:
假设要判断的边i,那么判断边i和边i-,边i和边i+1的夹角是否都为0()。 ----XDruid
代码: (这里我用的是Andrew算法)
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#define eps 1e-8
using namespace std; struct Point{
double x,y;
Point(double x=, double y=):x(x),y(y) {}
void input() { scanf("%lf%lf",&x,&y); }
};
typedef Point Vector;
int dcmp(double x) {
if(x < -eps) return -;
if(x > eps) return ;
return ;
}
template <class T> T sqr(T x) { return x * x;}
Vector operator + (Vector A, Vector B) { return Vector(A.x + B.x, A.y + B.y); }
Vector operator - (Vector A, Vector B) { return Vector(A.x - B.x, A.y - B.y); }
Vector operator * (Vector A, double p) { return Vector(A.x*p, A.y*p); }
Vector operator / (Vector A, double p) { return Vector(A.x/p, A.y/p); }
bool operator < (const Point& a, const Point& b) { return a.x < b.x || (a.x == b.x && a.y < b.y); }
bool operator >= (const Point& a, const Point& b) { return a.x >= b.x && a.y >= b.y; }
bool operator <= (const Point& a, const Point& b) { return a.x <= b.x && a.y <= b.y; }
bool operator == (const Point& a, const Point& b) { return dcmp(a.x-b.x) == && dcmp(a.y-b.y) == ; }
double Dot(Vector A, Vector B) { return A.x*B.x + A.y*B.y; }
double Length(Vector A) { return sqrt(Dot(A, A)); }
double Angle(Vector A, Vector B) { return acos(Dot(A, B) / Length(A) / Length(B)); }
double Cross(Vector A, Vector B) { return A.x*B.y - A.y*B.x; }
double angle(Vector v) { return atan2(v.y, v.x); } bool OnSegment(Point P, Point A, Point B) { //端点不算
return dcmp(Cross(A-P,B-P)) == && dcmp(Dot(A-P,B-P)) <= ;
}
int ConvexHull(Point* p, int n, Point* ch) {
sort(p,p+n);
int m = ;
for(int i=;i<n;i++) {
while(m > && Cross(ch[m-]-ch[m-], p[i]-ch[m-]) <= ) m--;
ch[m++] = p[i];
}
int k = m;
for(int i=n-;i>=;i--) {
while(m > k && Cross(ch[m-]-ch[m-], p[i]-ch[m-]) <= ) m--;
ch[m++] = p[i];
}
if(n > ) m--;
return m;
}
Point ch[],p[]; int main()
{
int t,n,i,j;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(i=;i<n;i++) p[i].input();
if(n <= ) { puts("NO"); continue; }
int m = ConvexHull(p,n,ch);
if(m <= ) { puts("NO"); continue; }
for(i=;i<m;i++) {
int cnt = ;
for(j=;j<n;j++)
if(OnSegment(p[j],ch[i],ch[(i+)%m]))
cnt++;
if(cnt < ) break;
}
if(i == m) puts("YES");
else puts("NO");
}
return ;
}
现在终于对自己的凸包版有了全面的了解了,妈妈再也不用担心我用错凸包了。哈哈。
POJ 1228 Grandpa's Estate --深入理解凸包的更多相关文章
- POJ 1228 - Grandpa's Estate 稳定凸包
稳定凸包问题 要求每条边上至少有三个点,且对凸包上点数为1,2时要特判 巨坑无比,调了很长时间= = //POJ 1228 //稳定凸包问题,等价于每条边上至少有三个点,但对m = 1(点)和m = ...
- POJ 1228 Grandpa's Estate(凸包)
Grandpa's Estate Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 11289 Accepted: 3117 ...
- POJ 1228 Grandpa's Estate 凸包 唯一性
LINK 题意:给出一个点集,问能否够构成一个稳定凸包,即加入新点后仍然不变. 思路:对凸包的唯一性判断,对任意边判断是否存在三点及三点以上共线,如果有边不满足条件则NO,注意使用水平序,这样一来共线 ...
- POJ 1228 Grandpa's Estate(凸包唯一性判断)
Description Being the only living descendant of his grandfather, Kamran the Believer inherited all o ...
- 简单几何(求凸包点数) POJ 1228 Grandpa's Estate
题目传送门 题意:判断一些点的凸包能否唯一确定 分析:如果凸包边上没有其他点,那么边想象成橡皮筋,可以往外拖动,这不是唯一确定的.还有求凸包的点数<=2的情况一定不能确定. /********* ...
- poj - 1228 - Grandpa's Estate
题意:原来一个凸多边形删去一些点后剩n个点,问这个n个点能否确定原来的凸包(1 <= 测试组数t <= 10,1 <= n <= 1000). 题目链接:http://poj. ...
- 【POJ】1228 Grandpa's Estate(凸包)
http://poj.org/problem?id=1228 随便看看就能发现,凸包上的每条边必须满足,有相邻的边和它斜率相同(即共线或凸包上每个点必须一定在三点共线上) 然后愉快敲完凸包+斜率判定, ...
- poj 1228 稳定凸包
Grandpa's Estate Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 12337 Accepted: 3451 ...
- 凸包稳定性判断:每条边上是否至少有三点 POJ 1228
//凸包稳定性判断:每条边上是否至少有三点 // POJ 1228 #include <iostream> #include <cstdio> #include <cst ...
随机推荐
- PHP清理跨站XSS xss_clean 函数 整理自codeigniter Security
PHP清理跨站XSS xss_clean 函数 整理自codeigniter Security 由Security Class 改编成函数xss_clean 单文件直接调用.BY吠品. //来自cod ...
- Mysql关键字 Mysql保留字列表 Mysql字段名
Mysql保留字列表.吠品整理. 尝试使用一个识别符,例如使用嵌入式MySQL 数据类型或函数名作为表名或列名,例如TIMESTAMP 或GROUP,会造成一个常见问题.允许你这样操作( 例如,ABS ...
- 分享一个我的JavaScript版GridView多功能表格
GridView是什么? GridView是由Mr.Co开发的一套开源的多功能表格插件,主要用于让页面开发者在开发中节省拼接Table表格和操作Table表格相关复杂操作的开发成本与时间.开发人员可以 ...
- 制作具有SSH、MySQL功能的Chroot
由于工作需求,需要在Linux上建立SSH.MySQL两个用户. 使这两个账户连接到跳板机后仅能执行有限的命令(SSH用户只能执行SSH命令,MySQL用户只能执行MySQL命令). MySQL账户C ...
- 兼容Android的水波纹效果
Android的水波纹效果只有高版本才有,我们希望自己的应用在低版本用低版本的阴影,高版本用水波纹,这怎么做呢?其实,只要分drawable和drawablev21两个文件夹就好了. 普通情况下的se ...
- System.currentTimeMillis()与SystemClock.uptimeMillis()
1.System.currentTimeMillis()获取的是系统的时间,可以使用SystemClock.setCurrentTimeMillis(long millis)进行设置.如果使用Syst ...
- UIApplicationDelegate
App受到干扰时,UIApplication会通知它的delegate对象,让delegate处理系统事件. 项目中的AppDelegate已经遵守了UIApplicationDelegate协议 ...
- IOS动画
基础动画 //创建基础动画 CABasicAnimation * basic = [CABasicAnimation animation]; //动画路径 basic.keyPath ...
- iOS-UIScrollView和UIPageControl的综合实力,滚动图,轮播图
本代码主要实现图片之间的切换 目录结构 代码 ViewController.m文件 #import "ViewController.h" @interface ViewContro ...
- KVC与KVO的实现原理
|KVC的用法 1.KVC既键值编码(Key Value Coding),基于NSKeyValueCoding协议,它是以字符串的形式来操作对象的成员变量,也就是通过字符串key来指定要操作的成员变量 ...