Grandpa's Estate - POJ 1228(稳定凸包)

刚开始看这个题目不知道是什么东东,后面看了大神的题解才知道是稳定凸包问题,什么是稳定凸包呢?所谓稳定就是判断能不能在原有凸包上加点,得到一个更大的凸包,并且这个凸包包含原有凸包上的所有点。知道了这个东西就简单了,直接求出来凸包后,然后判断每条边上的点是否超过三点就行了。

代码如下:

============================================================================================================================

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
using namespace std;

const double EPS = 1e-16;
const int MAXN = 1007;
const int oo = 1e9+7;

int sta[MAXN], top;

struct point
{
    double x, y;

    point(double x=0, double y=0):x(x), y(y){}
    point operator - (const point &t)const{
        return point(x-t.x, y-t.y);
    }
    double operator *(const point &t)const{
        return x*t.x + y*t.y;
    }
    double operator ^(const point &t)const{
        return x*t.y - y*t.x;
    }
}p[MAXN];
int Sign(double t)
{
    if(t > EPS)return 1;
    if(fabs(t) < EPS)return 0;
    return -1;
}
double Dist(point a, point b)
{
    return sqrt((a-b)*(a-b));
}
bool cmp(point a, point b)
{
    int t = Sign((a-p[0])^(b-p[0]));

    if(t == 0)
        return Dist(a, p[0]) < Dist(b, p[0]);
    return t > 0;
}
void Graham(int N)
{
    int k=0;

    for(int i=0; i<N; i++)
    {
        if(p[k].y>p[i].y || (Sign(p[k].y-p[i].y)==0 && p[k].x > p[i].x))
            k = i;
    }
    swap(p[0], p[k]);
    sort(p+1, p+N, cmp);

    sta[0]=0, sta[1]=1, top=1;

    if(N < 2)
    {
        top = N-1;
        return ;
    }

    for(int i=2; i<N; i++)
    {
        while(top>0 && Sign((p[i]-p[sta[top]])^(p[sta[top-1]]-p[sta[top]])) <= 0)
            top--;
        sta[++top] = i;
    }
}

int main()
{
    int T, N, i, j;

    scanf("%d", &T);

    while(T--)
    {
        scanf("%d", &N);

        for(i=0; i<N; i++)
            scanf("%lf%lf", &p[i].x, &p[i].y);

        Graham(N);
        sta[++top] = sta[0];

        for(i=0; i<top; i++)
        {
            int s=sta[i], e=sta[i+1];
            for(j=0; j<N; j++)
            {
                if(j==s || j==e)
                    continue;
                if(Sign( (p[s]-p[e])^(p[j]-p[e]) ) == 0)
                    break;
            }

            if(j == N)
                break;
        }

        if(i < top || top < 3)
            printf("NO\n");
        else
            printf("YES\n");
    }

    return 0;
}

Grandpa's Estate - POJ 1228(稳定凸包)

时间: 2024-10-10 13:52:11

Grandpa's Estate - POJ 1228(稳定凸包)的相关文章

Grandpa&#39;s Estate POJ - 1228

Grandpa's Estate POJ - 1228 题意:给一些点,问能否唯一确定一个凸包. 先求凸包,当且仅当每条边都至少三个点时可唯一确定一个凸包. 1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <algorithm> 5 using namespace std; 6 const int maxn=1010; 7 8 struct Node{ 9 i

poj 1228(稳定凸包)

Grandpa's Estate Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 12204   Accepted: 3430 Description Being the only living descendant of his grandfather, Kamran the Believer inherited all of the grandpa's belongings. The most valuable one

POJ 1228 Grandpa&#39;s Estate [稳定凸包]

Grandpa's Estate Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 13112   Accepted: 3697 Description Being the only living descendant of his grandfather, Kamran the Believer inherited all of the grandpa's belongings. The most valuable one

poj 1228 Grandpa&#39;s Estate (稳定凸包问题)

---恢复内容开始--- 题意:你的长辈给你留了块土地,然而这块土地是以一些钉子来界定的,题目要做的就是给你一堆钉子的坐标(也就是凸包上部分的点),然后问你能不能唯一确定这块土地 //不得不说知道题意后一脸懵逼.. 知识:稳定凸包 所谓稳定就是判断能不能在原有凸包上加点,得到一个更大的凸包,并且这个凸包包含原有凸包上的所有点. 举一个不稳定的例子 为什么说它不稳定呢?因为他可以加点来得到更大的凸包 那什么样子是稳定的呢? 因此我们可以知道当一个凸包稳定时,凸包的每条边上都要有至少三个点,若只有两

POJ 1228 Grandpa&#39;s Estate (稳定凸包)

读懂题意很关键,输入一个凸包上的点(没有凸包内部的点,要么是凸包顶点,要么是凸包边上的点),判断这个凸包是否稳定.所谓稳定就是判断能不能在原有凸包上加点,得到一个更大的凸包,并且这个凸包包含原有凸包上的所有点. 首先来了解什么是稳定的凸包. 比如有4个点: 这四个点是某个凸包上的部分点,他们连起来后确实还是一个凸包,但是它们不是稳定的, 我们发现,当凸包上存在一条边上的点只有端点两个点的时候,这个凸包不是稳定的,因为它可以在这条边外再引入一个点,构成一个新的凸包.但一旦一条边上存在三个点,那么不

POJ 1228 Grandpa&#39;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]; } 这样的话,求出来就是最简凸包,即点数尽量少的凸包,因

poj 1228 Grandpa&#39;s Estate(凸包)

Grandpa's Estate Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 11508   Accepted: 3188 Description Being the only living descendant of his grandfather, Kamran the Believer inherited all of the grandpa's belongings. The most valuable one

【POJ 1228】Grandpa&#39;s Estate 凸包

找到凸包后暴力枚举边进行$check$,注意凸包是一条线(或者说两条线)的情况要输出$NO$ #include<cmath> #include<cstdio> #include<cstring> #include<algorithm> #define N 1003 #define read(x) x = getint() using namespace std; inline int getint() { int k = 0, fh = 1; char c

【POJ】1228 Grandpa&#39;s Estate(凸包)

http://poj.org/problem?id=1228 随便看看就能发现,凸包上的每条边必须满足,有相邻的边和它斜率相同(即共线或凸包上每个点必须一定在三点共线上) 然后愉快敲完凸包+斜率判定,交上去wa了QAQ.原因是忘记特判一个地方....因为我们求的凸包是三点共线的凸包,在凸包算法中我们叉积判断只是>0而不是>=0,那么会有一种数据为所有点共线的情况,此时求出来的凸包上的点是>原来的点的(此时恰好符合答案NO,因为可以在这条线外随便点一个点就是一个凸包了...)然后特判一下.