zoukankan      html  css  js  c++  java
  • 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 was a piece of convex polygon shaped farm in the grandpa's birth village. The farm was originally separated from the neighboring farms by a thick rope hooked to some spikes (big nails) placed on the boundary of the polygon. But, when Kamran went to visit his farm, he noticed that the rope and some spikes are missing. Your task is to write a program to help Kamran decide whether the boundary of his farm can be exactly determined only by the remaining spikes.

    Input

    The first line of the input file contains a single integer t (1 <= t <= 10), the number of test cases, followed by the input data for each test case. The first line of each test case contains an integer n (1 <= n <= 1000) which is the number of remaining spikes. Next, there are n lines, one line per spike, each containing a pair of integers which are x and y coordinates of the spike.

    Output

    There should be one output line per test case containing YES or NO depending on whether the boundary of the farm can be uniquely determined from the input.

    Sample Input

    1
    6 
    0 0
    1 2
    3 4
    2 0
    2 4 
    5 0
    

    Sample Output

    NO
    题目难懂.
    题意:稳定凸包问题:给出n个点,问形成的凸包是否"稳定"。
    所谓稳定就是判断能不能在原有凸包上加点,得到一个更大的凸包,并且这个凸包包含原有凸包上的所有点。
    这个解释感觉容易懂,引自:http://blog.csdn.net/acdreamers/article/details/10023615/

    我的看法其实就是一条边上要除了顶点外至少还要一个点.那样的话才会稳定.
    以我之拙见。。网上的解法是有问题的。。给出我的解法和别人的一组测试数据。POJ的数据可能水了点..网上的解法很多都是将在凸包上边上但不是顶点的点加进去。然后再用两个叉积条件判断。
    我是直接枚举每条边,然后枚举所有点,除了顶点之外至少还要有一个点在边上才行(题目说了点都在凸包顶点或者边上,,这样更说明了如果用网上的解法去求凸包是没有意义的,因为已经排好序了,所有的点再加一次,Stack应该就是p了)。
    还要加个条件就是点数不能小于6,因为就算是三角形都至少需要6个点才稳定。
    测试数据:
    1
    6
    0 0 1 1 2 2 3 3 2 3 0 3
    NO
    
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <math.h>
    #include <algorithm>
    #include <stdlib.h>
    using namespace std;
    const int N = 1005;
    const double eps = 1e-8;
    struct Point {
        int x,y;
    }p[N],Stack[N];
    struct Line{
        Point a,b;
    }line;
    int n;
    int cross(Point a,Point b,Point c){
        return (a.x-c.x)*(b.y-c.y)-(a.y-c.y)*(b.x-c.x);
    }
    double dis(Point a,Point b){
        return  sqrt((double)((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)));
    }
    int cmp(Point a,Point b){
        if(cross(a,b,p[0])>0) return 1;
        if(cross(a,b,p[0])==0&&dis(b,p[0])-dis(a,p[0])>eps) return 1;
        return 0;
    }
    bool Graham(){
        int k=0;
        for(int i=1;i<n;i++){
            if(p[i].y<p[k].y||(p[i].y==p[k].y)&&(p[i].x<p[k].x)) k=i;
        }
        swap(p[0],p[k]);
        sort(p+1,p+n,cmp);
        int top =2;
        Stack[0] = p[0];
        Stack[1] = p[1];
        Stack[2] = p[2];
        for(int i=3;i<n;i++){
            while(top>=1&&cross(p[i],Stack[top],Stack[top-1])>=0) top--;
            Stack[++top] = p[i];
        }
        int cnt ;
        Stack[top+1] = Stack[0];
        for(int i=0;i<=top;i++){
            line.a = Stack[i];
            line.b = Stack[i+1];
            cnt =0;
            for(int j=0;j<n;j++){
                if(line.a.x == p[j].x && line.a.y == p[j].y) continue;  ///除去自身
                if(line.b.x == p[j].x && line.b.y == p[j].y) continue;
                if(cross(line.a,line.b,p[j])==0){
                    cnt++;
                    break;
                }
            }
            if(cnt==0) return false;
        }
        return true;
    }
    int main()
    {
        int tcase;
        scanf("%d",&tcase);
        while(tcase--){
            scanf("%d",&n);
            for(int i=0;i<n;i++){
                scanf("%d%d",&p[i].x,&p[i].y);
            }
            if(n<6){
                printf("NO
    ");continue;
            }
            bool ans = Graham();
            if(ans) printf("YES
    ");
            else printf("NO
    ");
        }
        return 0;
    }
  • 相关阅读:
    [转]zookeeper-端口说明
    ACM-ICPC(9/26)
    ACM-ICPC(9/25)
    Linux的文件权限与目录配置
    Uva 11468 AC自动机或运算
    Uva 11922 Splay
    HDU 6214 最小割边
    Uva 10559 消除方块
    HDU 6194 后缀数组
    Uva 11491 暴力贪心
  • 原文地址:https://www.cnblogs.com/liyinggang/p/5451222.html
Copyright © 2011-2022 走看看