zoukankan      html  css  js  c++  java
  • POJ 1696 Space Ant

    POJ_1696

        一个比较直观的思路就是,如果现在我在某个点,那么我就要沿着刚刚走过的一段的方向看过去,然后视线逐渐向左转,遇到第一个点为止,然后就冲那个点走过去即可。对于起点的选择也并不难想到,挑一个y值最小的点即可,初始的视线方向就定为沿x轴正方向,如果有多个y值最小的点,那就随便选一个,因为无论选哪一个最终都是可以走出合法的路线的。

        剩下一个问题就是如果判断视线左转时遇到的第一个点了,出于方便处理的考虑,我们可以选用左转的角度theta来衡量,而theta可以通过点积及相关运算得到。同时,我们注意到theta是在0到pi之间的,于是我们也可以选用一个等价的变量cos(theta)来衡量,而且后者更简便一些,毕竟前者也是通过后者做acos的运算得到的。

        这个题有一个地方我没有去处理,就是如果存在重合的点的话,这样做就会出现除0的情况。但是根据题意来看应该不会有重点的情况,没考虑这点的情况下交了之后也AC了,所以数据里面应该也没有重点的情况。

    #include<stdio.h>
    #include<string.h>
    #include<math.h>
    #define MAXD 60
    int N, vis[MAXD], S;
    double x[MAXD], y[MAXD], px, py, cx, cy;
    void init()
    {
    int i, j;
    py = 110;
    scanf("%d", &N);
    for(i = 1; i <= N; i ++)
    {
    scanf("%d%lf%lf", &j, &x[i], &y[i]);
    if(y[i] < py)
    py = y[i], px = x[i] - 1, S = i;
    }
    }
    void solve()
    {
    int i, j, k;
    double t, a, len;
    cx = x[S], cy = y[S];
    memset(vis, 0, sizeof(vis));
    vis[S] = 1;
    printf("%d %d", N, S);
    for(i = 1; i < N; i ++)
    {
    a = -2, len = sqrt((cx - px) * (cx - px) + (cy - py) * (cy - py));
    for(j = 1; j <= N; j ++)
    if(!vis[j])
    {
    t = ((cx - px) * (x[j] - cx) + (cy - py) * (y[j] - cy)) / (sqrt((x[j] - cx) * (x[j] - cx) + (y[j] - cy) * (y[j] - cy)) * len);
    if(t > a)
    a = t, k = j;
    }
    vis[k] = 1;
    px = cx, py = cy;
    cx = x[k], cy = y[k];
    printf(" %d", k);
    }
    printf("\n");
    }
    int main()
    {
    int t;
    scanf("%d", &t);
    while(t --)
    {
    init();
    solve();
    }
    return 0;
    }


  • 相关阅读:
    【题解】字母 (letter)
    【题解】【原创题目】薇尔莉特
    【题解】Query on a tree III [SP1487] [Bzoj1803]
    11个炫酷的 Linux 终端命令
    A light-weight client-side OAuth library for Java
    android下的异步任务
    OAuth相关知识
    显示单位px、dip以及sp的区别
    Arduino连接SHT10温湿度传感器--返回值不正常解决办法
    blueterm蓝牙超级终端(源码)
  • 原文地址:https://www.cnblogs.com/staginner/p/2346147.html
Copyright © 2011-2022 走看看