hrbustoj 1318:蛋疼的蚂蚁(计算几何,凸包变种,叉积应用)

蛋疼的蚂蚁

Time Limit: 1000 MS     Memory Limit: 65536 K

Total Submit: 39(22 users)    Total Accepted: 26(21 users) Rating:   

Special Judge: No

 

Description

大千世界无奇不有,最近科学家发现一种蚂蚁,它头部只有一只左眼,并且

三只脚在身子的右侧,因此:1,它不能转向右侧。2,它的行走会留下一条红印。3,它行走不会在经过以前

走过的红印。

这种蚂蚁需要每天吃一个食物,这个食物坐落在平面坐标系中,没有两个植物会在同一点。蚂蚁一天会找到一个食物,然后它就在那里

过完一天,第二天它会再出发寻找食物。问题是寻找一条道路让蚂蚁活的时间最长。

 

蚂蚁的起始点从y坐标最小开始,如果y相同则x最小起。

Input

首先输入测试的组数m,(1<=m<=10).对于每组首先输入n,代表植物的个数(1<=n<=50)

然后n 行是每个植物的数据。每行有三个整数组成,第一个数是惟一的序号(1...n),然后跟着两个整数x,y代表植物的坐标位置。

序号是按升序给出来的。假设坐标系最大是100.

Output

对于每组数据单独输出一行,首先输出蚂蚁能够吃的植物个数,然后是这条路线植物的序号数。

Sample Input

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

 

Sample Output

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

Hint

计算几何

Source

2012 Spring Contest 4 - Search Technology

Author

鲁学涛


 

  计算几何,凸包变种,叉积应用

  这道题是 poj1696(分析见poj 1696:Space Ant(计算几何,凸包变种,极角排序))的中文版,重新练习了一下叉积的应用,感觉更条理了。

  代码:

 1 #include <stdio.h>
 2 #include <cmath>
 3 #define eps 1e-10
 4 typedef struct {
 5     double x,y;
 6 }Point;
 7 
 8 double Cross(Point a,Point b,Point c)    //求叉积
 9 {
10     return (c.x-a.x)*(b.y-a.y)-(c.y-a.y)*(b.x-a.x);
11 }
12 
13 void findway(Point p[],int n)
14 {
15     printf("%d",n);    //输出点数
16     //找到开始的点
17     int i,cur=1;
18     for(i=2;i<=n;i++){
19         if(fabs(p[i].y-p[cur].y)<eps){    //相等
20             if(p[i].x < p[cur].x)
21                 cur = i;
22         }
23         else if(p[i].y < p[cur].y)    //小于
24             cur = i;
25     }
26     //开始找路,始终找最右边的路
27     bool isw[51]={0};    //记录走过了没有
28     isw[cur] = true;
29     printf(" %d",cur);    //输出第一个点
30     while(1){
31         int next;
32         for(i=1;i<=n;i++){    //假设下一个点
33             if(!isw[i])
34                 break;
35         }
36         next = i;
37         if(i>n)    //如果都被访问过,循环结束
38             break;
39         for(i=1;i<=n;i++){
40             if(!isw[i] && i!=next && Cross(p[cur],p[next],p[i])>0)
41                 next = i;
42         }
43         cur = next;
44         isw[cur] = true;
45         printf(" %d",cur);    //输出当前确定的点
46     }
47     printf("\n");
48     return ;
49 }
50 int main()
51 {
52     int m,n;
53     scanf("%d",&m);
54     while(m--){
55         scanf("%d",&n);
56         Point p[51];
57         int i;
58         for(i=1;i<=n;i++)    //输入点集
59             scanf("%d%lf%lf",&i,&p[i].x,&p[i].y);
60         findway(p,n);
61     }
62     return 0;    
63 }

 

Freecode : www.cnblogs.com/yym2013

posted @ 2014-04-05 23:05  Freecode#  阅读(306)  评论(0编辑  收藏  举报