poj 1696

题目概述

坐标内有N个点(x,y),每个点序号为n,所有点的横坐标不同,纵坐标也不同,从纵坐标最小的点开始,可向其他任意一个点做线段,但除第一次以外,其后每次只能在上一条线段所在直线的逆时针一侧找点连线,且所做线段不能与已经存在的线段相交,按序号升序给出所有点,问最多可连接多少个点,并求其连接的顺序

时限

1000ms/3000ms

输入

第一行正整数times,其后times组数据,每组数据第一行正整数N,其后N行,每行3个正整数n,x,y

限制

1<=times<=10;1<=N<=50;1<=x,y<=100

输出

每行第一个数N,为最多可连接的点数,其后N个数,为点的序号,按连接顺序输出

样例输入

2
10
1 4 5
2 9 8
3 5 9
4 1 7
5 3 2
6 6 3
7 10 10
8 8 1
9 2 4
10 7 6
14
1 6 11
2 11 9
3 8 7
4 12 8
5 9 20
6 3 2
7 1 6
8 2 13
9 15 1
10 14 17
11 13 19
12 5 18
13 7 3
14 10 16

样例输出

10 8 7 3 4 9 5 6 2 1 10
14 9 10 11 5 12 8 7 6 13 4 14 1 3 2

讨论

计算几何,可以算是凸包吧,不过也只是卷包裹的思想而已,应该都有,实现上难度也不是特别大,类似于堆排序,每次取一个和上一条线段角度最小的点,换到前面,不过判断函数每次都要发生变化,直接用堆可能会略微麻烦
最多的个数必然是所有点都可连接,因为多于2个点时凸包总是存在的,能构造凸包,就能以相同思想把所有点连起来
另外,这题数据略水,平方级复杂度还能0ms

题解状态

136K,0MS,C++,1038B

题解代码

#include
#include
#include
#include
#include
using namespace std;
#define INF 0x3f3f3f3f  
#define MAXN 53
#define memset0(a) memset(a,0,sizeof(a))
#define EPS 1e-6

struct I//item 每个点的结构
{
    int n, x, y;//序号 横纵坐标
}Is[MAXN];//存储每个点的原始数据
int X, Y;//判断函数pred2中的公共起点坐标
int xp(int x1, int y1, int x2, int y2, int x3, int y3)
{
    return (x1 - x2)*(y3 - y2) - (y1 - y2)*(x3 - x2);
}
bool pred(I &a, I &b)//判断函数1 第一个点取y最小者
{
    return a.y < b.y;
}
bool pred2(I &a, I &b)//判断函数2 若点a相对于点(X,Y)在点b的逆时针方向 返回1 这相当于重载小于号
{
    return xp(a.x, a.y, X, Y, b.x, b.y) < 0;
}
void fun(int N)
{
    for (int p = 0; p < N; p++)
        scanf("%d%d%d", &Is[p].n, &Is[p].x, &Is[p].y);//input
    I *lowest = min_element(Is, Is + N, pred);//取出第一个点
    for (int p = 0; p < N; p++) {
        swap(*lowest, Is[p]);//交换
        X = Is[p].x;
        Y = Is[p].y;//更新判断函数的条件
        lowest = max_element(Is + p + 1, Is + N, pred2);//以新条件寻找下一个点 同时搜索范围更小了
    }
    printf("%d", N);//output
    for (int p = 0; p < N; p++)
        printf(" %d", Is[p].n);//output
    printf("\n");//output
}
int main(void)
{
    //freopen("vs_cin.txt", "r", stdin);
    //freopen("vs_cout.txt", "w", stdout);

    int times;
    scanf("%d", ×);//input
    while (times--) {
        int N;
        scanf("%d", &N);//input
        fun(N);
    }
}

你可能感兴趣的:(计算几何.凸包,poj)