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;
    }


  • 相关阅读:
    java 保留2位小数 转载
    android表格效果ListView隔行变色
    安卓学习之排版RelativeLayout表格布局
    安卓学习之如何关闭所有的activity
    安卓学习之android 数据传递详解(Serialization、Parcelable、Parcel、Intent、Bundle)
    [转]Android 实现TextView中文字链接的方式
    OOP编程iBatis 学习笔记之二 单表增删改操作
    OOP编程iBatis 学习笔记之三 2个表或者多表关联查询
    安卓学习之排版TableLayout表格布局
    (原创)C#反射知识分享之二
  • 原文地址:https://www.cnblogs.com/staginner/p/2346147.html
Copyright © 2011-2022 走看看