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

本文详细解析了POJ平台上的1696题,通过运用叉积原理及深度优先搜索算法解决路径规划问题。文章介绍了题目背景、解题思路和关键步骤,旨在帮助读者理解并掌握此类问题的解决方法。

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 }

 

 
 

转载于:https://www.cnblogs.com/acSzz/archive/2012/08/27/2657990.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值