zoukankan      html  css  js  c++  java
  • 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("
    ");
    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

  • 相关阅读:
    MVC三层架构
    JavaScript,你好!(二)
    HTML你好!
    Typora,你好!
    安装mysqlmysql-5.7.24-linux-glibc2.12-x86_64
    sizeof与strlen的区别
    printf格式化输出
    java泛型讲解
    双系统删除Linux系统
    kali破解wifi密码
  • 原文地址:https://www.cnblogs.com/yym2013/p/3647701.html
Copyright © 2011-2022 走看看