zoukankan      html  css  js  c++  java
  • gym 101164 H.Pub crawl 凸包

    题目链接:http://codeforces.com/gym/101164/attachments

    题意:对于已知的 n 个二维坐标点,要求按照某种特定的连线方式将尽可能多的点连接(任意相邻的 3 个点 a , b , c ,点 c 必须在有向线段 ab 的左侧。问最多可以连多少点,并给出连线顺序。

    思路:因为连接最多的点,尽量让形成一个凸包将点包起来,形成螺旋式的连接所有的点,凸包模板;

    #pragma comment(linker, "/STACK:1024000000,1024000000")
    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<string>
    #include<queue>
    #include<algorithm>
    #include<stack>
    #include<cstring>
    #include<vector>
    #include<list>
    #include<set>
    #include<map>
    #include<stdlib.h>
    #include<time.h>
    #include<bits/stdc++.h>
    using namespace std;
    #define LL long long
    #define pi (4*atan(1.0))
    #define bug(x)  cout<<"bug"<<x<<endl;
    
    const int N=1e5+10,M=1e6+10,inf=2147483647;
    const LL INF=1e18+10,mod=2147493647;
    const double eps = 1e-8;
    const double PI = acos(-1.0);
    int sgn(double x)
    {
        if(fabs(x) < eps)return 0;
        if(x < 0)return -1;
        else return 1;
    }
    struct Point
    {
        double x,y;
        int pos;
        Point() {}
        Point(double _x,double _y)
        {
            x = _x;
            y = _y;
        }
        Point operator -(const Point &b)const
        {
            return Point(x - b.x,y - b.y);
        }
        //叉积
        double operator ^(const Point &b)const
        {
            return x*b.y - y*b.x;
        }
    //点积
        double operator *(const Point &b)const
        {
            return x*b.x + y*b.y;
        }
    
    }a[N];
    double dist(Point a,Point b)
    {
        return sqrt((a-b)*(a-b));
    }
    int n;
    const int MAXN = 5010;
    Point listt[MAXN];
    int Stack[MAXN],top,vis[N]; //相对于listt[0]的极角排序
    vector<int>ans;
    bool _cmp(Point p1,Point p2)
    {
        double tmp = (p1-listt[0])^(p2-listt[0]);
        if(sgn(tmp) > 0)return true;
        else if(sgn(tmp) == 0 && sgn(dist(p1,listt[0]) - dist(p2,listt[0])) <= 0) return true;
        else return false;
    }
    void Graham()
    {
        Point p0;
        int k = 0;
        p0 = listt[0]; //找最下边的一个点
        for(int i = 1; i < n; i++)
        {
            if( (p0.y > listt[i].y) || (p0.y == listt[i].y && p0.x > listt[i].x) )
            {
                p0 = listt[i];
                k = i;
            }
        }
        swap(listt[k],listt[0]);
        sort(listt+1,listt+n,_cmp);
        int m=1;
        Stack[0] = 0;
        Stack[1] = 1;
        vis[0]=1;
        vis[1]=1;
        top = 2;
        while(top<n)
        {
            for(int i = 2; i < n; i++)
            {
                if(vis[i])continue;
                while(top > 1 && sgn((listt[Stack[top-1]]-listt[Stack[top-2]])^(listt[i]-listt[Stack[top-2]])) <= 0)
                top--,vis[Stack[top]]=0;
                Stack[top++] = i;
                vis[i]=1;
            }
        }
    }
    int main()
    {
        scanf("%d",&n);
        for(int i=0;i<n;i++)
            scanf("%lf%lf",&listt[i].x,&listt[i].y),listt[i].pos=i+1;
        Graham();
        printf("%d
    ",n);
        for(int i=0;i<n;i++)
            printf("%d ",listt[Stack[i]].pos);
        return 0;
    }
    /*
    5
    0 4
    3 0
    7 11
    9 1
    13 8
    */
  • 相关阅读:
    如何快速实现一个command
    引用mvvmlight dll ,操作command
    ANSI X9.8标准 PIN xor PAN获取PIN BlOCK
    关于Application.DoEvents()==转
    进程间通信方式【转】
    30岁后程序员的出路[转]
    git实用操作21条
    where T:new() 是什么意思
    使用Chrome console提取页面数据
    Maven入门2-pom.xml文件与settings.xml文件
  • 原文地址:https://www.cnblogs.com/jhz033/p/7252677.html
Copyright © 2011-2022 走看看