• poj 1696 Space Ant (几何 : 叉积 应用 + dfs)


    http://poj.org/problem?id=1696

    题意:

    题意:一张图上给出n个点的坐标(xi,yi),其中xi,yi均为正整数。记这n个点中,拥有最小y的点为A,你开始从点(0, yA)开始走向点A,然后,你可以随意选择径直走去另外的点,但必须满足一下3个条件:

    1:只能向左转向(也可直走)。

    2:走过的路径为留下一条红色的轨迹。

    3:不能越过这条红色的轨迹。

    问你最多能到达几个点,并且按到达的顺序输出各个点的标号。

     

    poj <wbr>1696 <wbr>:Space <wbr>Ant <wbr>(几何:叉积)

     

    题解:

    叉积 + dfs

    易证:按照一定的顺序,每次选择当前左转角度最小的点(相等则选距离最近的点),
    必能按条件遍历所有的点。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<cmath>
     4 #include<iostream>
     5 #include<algorithm>
     6 #include<set>
     7 #include<map>
     8 #include<queue>
     9 #include<vector>
    10 #include<string>
    11 #define Min(a,b) a<b?a:b
    12 #define Max(a,b) a>b?a:b
    13 #define CL(a,num) memset(a,num,sizeof(a));
    14 #define maxn  60
    15 #define eps  1e-8
    16 #define inf 100000000
    17 #define mx 1<<60
    18 #define ll   __int64
    19 using namespace std;
    20 
    21 struct point
    22 {
    23     int id ;
    24     int ord ;
    25     double x;
    26     double y;
    27 }p[maxn];
    28 bool vis[maxn] ;
    29 double ans ;
    30 int  n,num ;
    31 int det(int x1,int y1,int x2,int y2)
    32  {
    33      return x1*y2 - x2*y1;
    34  }
    35  int cross(point a,point b,point c)
    36  {
    37      return det(b.x - a.x,b.y - a.y,c.x - a.x,c.y - a.y);
    38  }
    39 double dis(point a,point b)
    40 {
    41     double  x1 = a.x;
    42     double y1 = a.y;
    43     double x2 = b.x;
    44     double y2 = b.y ;
    45     return   (x2 - x1 )*(x2 - x1) + (y2-y1)*(y2 - y1);
    46 }
    47 void dfs(int pre,int num)
    48 {
    49 
    50     if(num == n) return ;
    51     int mi = 1;
    52     while(vis[mi])mi++;
    53     for(int i = mi + 1 ;i <= n;i++)
    54     {
    55         if(vis[i])continue ;
    56         double w = cross(p[pre],p[mi],p[i]);
    57         if(w  < - eps) mi = i;
    58         if(w < fabs(eps) && dis(p[pre],p[i]) < dis(p[pre],p[mi])) mi = i;
    59     }
    60     p[mi].ord = num + 1;
    61 
    62     vis[mi] = true ;
    63     dfs(mi,num + 1) ;
    64 }
    65 bool cmp(point a,point b)
    66 {
    67     return  a.ord < b.ord ;
    68 }
    69 int main()
    70 {
    71     int i,j;
    72     //freopen("data.txt","r",stdin);
    73     int  t;
    74     scanf("%d",&t);
    75 
    76     while(t--)
    77     {
    78         scanf("%d",&n);
    79         CL(vis,false );
    80         int mi = inf ;
    81         for(i = 1 ; i<= n;i++)
    82         {
    83             scanf("%d%lf%lf",&p[i].id,&p[i].x,&p[i].y);
    84             if(mi == inf||p[mi].y > p[i].y) mi =  i;
    85         }
    86         vis[mi] = true ;
    87 
    88         p[mi].ord = 1 ;
    89         dfs(mi,1);
    90         sort(p + 1 ,p + 1 + n,cmp);
    91         printf("%d",n);
    92         for(i = 1;i <=n;i++)
    93         {
    94 
    95             printf(" %d",p[i].id) ;
    96         }
    97         printf("\n");
    98     }
    99 }

     

     

  • 相关阅读:
    Oracle常见故障问题
    java前后端加密(转载)
    美团在Redis上踩过的一些坑-3.redis内存占用飙升(转载)
    tomcat访问(access)日志配置、记录Post请求参数(转)
    angular2学习资源汇总
    Ionic2 常见问题及解决方案
    URL Schemes(转载)
    (四)文本编辑器Vim/Vi
    C#接口作用的深入理解
    C#连接SQL Server数据库进行简单操作
  • 原文地址:https://www.cnblogs.com/acSzz/p/2657990.html
Copyright © 2020-2023  润新知