POJ 1696 /// 凸包

题目大意:

不能向左拐 不能重复走

就是求一个螺旋凸包

把已经是凸包内的点标记一下就行

因为凸包的性质 所有点都能走到

注意起点的选择 还有 反复求凸包的过程中边界的改变

#include <cstdio>
#include <algorithm>
#include <string.h>
#include <cmath>
using namespace std;

const int N=55;
const double eps=1e-10;
double add(double a,double b) {
    if(abs(a+b)<eps*(abs(a)+abs(b))) return 0;
    return a+b;
}
struct P {
    double x,y; int id;
    P(){};
    P(double _x,double _y,int _id):x(_x),y(_y),id(_id){}
    P operator -(P p) {
        return P(add(x,-p.x),add(y,-p.y),0); };
    P operator +(P p) {
        return P(add(x,p.x),add(y,p.y),0); };
    P operator *(double d) {
        return P(x*d,y*d,0); };
    double dot(P p) {
        return add(x*p.x,y*p.y); };
    double det(P p) {
        return add(x*p.y,-y*p.x); };
}p[N], ans[N];
bool flag[N];
int  n;

bool cmp(P a,P b) {
    if(a.x==b.x) return a.y<b.y;
    return a.x<b.x;
}
void solve(int st) {
    memset(flag,0,sizeof(flag));
    int k=0, t=1;
    while(k<n) {
        for(int i=st;i<n;i++)
            if(flag[p[i].id]==0) {
                while(k>t && (ans[k-1]-ans[k-2]).det(p[i]-ans[k-1])<=0)
                    k--, flag[ans[k].id]=0;
                ans[k++]=p[i]; flag[p[i].id]=1;
            }
        t=k;
        for(int i=n-2;i>=0;i--)
            if(flag[p[i].id]==0) {
                while(k>t && (ans[k-1]-ans[k-2]).det(p[i]-ans[k-1])<=0)
                    k--, flag[ans[k].id]=0;
                ans[k++]=p[i]; flag[p[i].id]=1;
            }
        t=k; st=0; // 注意边界的修改
    }
}

int main()
{
    int t; scanf("%d",&t);
    while(t--) {
        scanf("%d",&n);
        double miny=150.0;
        for(int i=0;i<n;i++) {
            scanf("%d%lf%lf",&p[i].id,&p[i].x,&p[i].y);
            miny=min(miny,p[i].y);
        }
        sort(p,p+n,cmp);
        int t; /// 起点应该取最低的一点 即y最小的一点
        for(int i=0;i<n;i++)
            if(p[i].y==miny) t=i;
        solve(t);
        printf("%d ",n);
        for(int i=0;i<n;i++)
            printf("%d ",ans[i].id); printf("\n");
    }

    return 0;
}

原文地址:https://www.cnblogs.com/zquzjx/p/9612443.html

时间: 2024-11-13 10:57:49

POJ 1696 /// 凸包的相关文章

Space Ant - POJ 1696 (凸包)

题目大意:给一些散列点然后初始点是坐标最下面最左面的点,然后只能往左走,求出来最多可以经过多少个点,把序号输出出来. 分析:先求出来初始的点,然后不断排序找出来最近的凸点....复杂度是 n^2*log(n)....不多点很少,所以随意玩. 代码如下: ===================================================================================================================== #incl

poj 1113 凸包周长

Wall Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 33888   Accepted: 11544 Description Once upon a time there was a greedy King who ordered his chief Architect to build a wall around the King's castle. The King was so greedy, that he w

poj 1696 叉积理解

Space Ant Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 3967   Accepted: 2489 Description The most exciting space discovery occurred at the end of the 20th century. In 1999, scientists traced down an ant-like creature in the planet Y19

POJ 1696

这题是明显的TU包变形. 使用卷包裹法可解,而且是必定可以经过所有点的.直观可知,当经过某点后,相当于把之前的点抹去,求剩下点的TU包,递归下去,也就能把点全部经过了. 于是,只需把经过的点标记一下就可以了. #include <iostream> #include <cstdio> #include <algorithm> #include <queue> #include <cmath> using namespace std; const

poj 1873 凸包+枚举

The Fortified Forest Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 6198   Accepted: 1744 Description Once upon a time, in a faraway land, there lived a king. This king owned a small collection of rare and valuable trees, which had been

POJ 1696 Space Ant(点积的应用)

Space Ant 大意:有一只蚂蚁,每次都只向当前方向的左边走,问蚂蚁走遍所有的点的顺序输出.开始的点是纵坐标最小的那个点,开始的方向是开始点的x轴正方向. 思路:从开始点开始,每次找剩下的点中与当前方向所形成的夹角最小的点,为下一个要走的点(好像就是犄角排序,我不是很会),夹角就是用点积除以两个向量的距离,求一下acos值. 之前一直用叉积做,做了好久样例都没过,发现用错了... 题目挺好的,有助于理解点积与叉积 1 struct Point{ 2 double x, y; 3 int id

POJ 2079 凸包最大内接三角形

Triangle Time Limit: 3000MS   Memory Limit: 30000K Total Submissions: 8038   Accepted: 2375 Description Given n distinct points on a plane, your task is to find the triangle that have the maximum area, whose vertices are from the given points. Input

POJ 1113 凸包模板题

上模板. #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <cmath> #include <vector> #include <utility> #include <stack> #include <queue> #include <map> #include

poj 1696 Space Ant (极角排序)

链接:http://poj.org/problem?id=1696 Space Ant Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 3077   Accepted: 1965 Description The most exciting space discovery occurred at the end of the 20th century. In 1999, scientists traced down an a