poj 1696

来源:互联网 发布:js传值到jsp 编辑:程序博客网 时间:2024/04/30 15:00

题目概述

坐标内有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<cstdio>#include<cstring>#include<algorithm>#include<cmath>#include<stack>using namespace std;#define INF 0x3f3f3f3f  #define MAXN 53#define memset0(a) memset(a,0,sizeof(a))#define EPS 1e-6struct 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", &times);//input    while (times--) {        int N;        scanf("%d", &N);//input        fun(N);    }}
0 0
原创粉丝点击