UVA 10153 - New Horizons WA20次 下面是WA代码

The Problem

Yertle has determined that the number of objects he can see, and hence rule, depends on the height of his throne. Your task, as Minister of Computing and Vertigo (a new combined Super Ministry), is to determine which objects Yertle would see should he build his throne to a particular height.

Standard input consists of several test cases, each containing:

  • A floating point number on a line by itself, specifying the diameter of Yertle's planet in "flipper lengths".
  • A line containing three floating point numbers: the height of Yertle's throne (in flipper lengths), the latitude of Yertle's throne (between -90 and +90 degrees), the longitude of Yertle's throne (between 0 and 360 degrees).
  • An integer n on a line by itself, specifying the number of objects on the surface of Yertle's planet.
  • n more lines, each containing three floating point numbers and a string of alphabetic and space characters. Each line indicates the height, latitude, longitude and name of an object on the surface of Yertle's planet.

All distances are in flipper lengths, and all latitudes and longitudes are in degrees. Floating point values are formatted as a string of decimal digits with an optional decimal point and sign. The fields in the input are separated by exactly one space character. You may assume that no object hides another; only the horizon limits Yertle's view.

For each test case, standard output consists of:

  • The list of objects whose tops are visible to Yertle, in alphabetical order, followed by a blank line.

Sample Input

20000.0
100.0 45.0 100.0
3
2.0 46.0 99.0 Cat
20.0 -45.0 260.0 House
5.0 45.1 100.2 Blueberry Bush
6.0
3.0 90.0 0.0
2
0.0 30.00 0.0 Ant on the horizon
0.1 30.00 0.0 Cat on the horizon

Sample Output

Blueberry Bush
Cat

Cat on the horizon

 

 

 //题意 在一个半径为r的星球上, 站着一个高度为h的人, 星球上还有其它东西,阿猫阿狗之类的,它们也有自己的高度,还知道人和这些东西的经纬度, 问你这人能看到哪些东西,将它们的名称按字母排序后输出。

#include <iostream>
#include <cmath>
#include <cstring>
#include<cstdio>
#include<algorithm>
#include<map>
using namespace std;
map <string, int>::iterator it;
const int maxn=10005;
const double Pi=acos(-1.0);
const double EP=1e-8;
double r;
struct Node{
    double lat, lng, h;
}node[maxn];
struct Point{double x, y;}man, p, c;
struct Line{double a, b, c;}l1;
Line makeline(Point p1, Point p2){
    Line t1;
    int sign=1;
    t1.a=p2.y-p1.y;
    if(t1.a<0){
        t1.a*=-1;
        sign=-1;
    }
    t1.b=sign*(p1.x-p2.x);
    t1.c=sign*(p1.y*p2.x-p1.x*p2.y);
    return t1;
}
double dist(Point a, Point b){
    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
double max(double a, double b){
    return a>b?a:b;
}
double min(double a, double b){
    return a<b?a:b;
}
bool between(Point op, Point sp, Point ep){
    if(op.x<=max(sp.x,ep.x)&&op.x>=min(sp.x,ep.x)&&op.y<=max(sp.y,ep.y)&&op.y>=min(sp.y,ep.y))
    return true;
    return false;
}

double line_dist(double lng1,double lat1,double lng2,double lat2)//求球面上两点的距离
{
       double dlng=fabs(lng1-lng2)*Pi/180;
       while (dlng>=Pi+Pi)
       dlng-=(Pi+Pi);
       if (dlng>Pi)
       dlng=Pi+Pi-dlng;
       lat1*=Pi/180,lat2*=Pi/180;
       return r*acos(cos(lat1)*cos(lat2)*cos(dlng)+sin(lat1)*sin(lat2));;
}
Point vert_p(Point p1, Line l1){
    Point p2;
    p2.x=(l1.b*(l1.b*p1.x-l1.a*p1.y)-l1.a*l1.c)/(l1.a*l1.a+l1.b*l1.b);
    p2.y=(l1.a*(l1.a*p1.y-l1.b*p1.x)-l1.b*l1.c)/(l1.a*l1.a+l1.b*l1.b);
    return p2;
}

int main(){
    //freopen("1.txt", "r", stdin);
    int n, i, sum;
    double d, angle, d1, d2;
    char s[maxn][80];
    man.x=0;c.x=0;c.y=0;
    while(scanf("%lf", &r)!=EOF){
        map <string, int> mp;
        sum=0;r/=2;
        scanf("%lf%lf%lf", &node[0].h, &node[0].lat, &node[0].lng);
        man.y=r+node[0].h;
        scanf("%d", &n);
        for(i=1; i<=n; i++){
            scanf("%lf%lf%lf ", &node[i].h, &node[i].lat, &node[i].lng);
            gets(s[i]);
            d=line_dist(node[0].lng-180, node[0].lat, node[i].lng-180, node[i].lat);
            angle=d/r;
            p.x=(r+node[i].h)*sin(angle);
            p.y=(r+node[i].h)*cos(angle);
            l1=makeline(p, man);
            Point t=vert_p(c, l1);
            d1=dist(c, t);
            d2==min(dist(c, man), dist(c, p));
            //if(fabs(node[i].h)<EP)continue;
            if(between(t, man, p))
                d=d1;
            else
                d=d2;
            if(fabs(d1-d2)<EP&&node[i].h<EP)continue;
          //  if(d1<r-EP&&fabs(d-r)<EP){
           //     mp[s[i]]++;
           //    continue;
          //  }
            if(d>=r-EP||(fabs(p.x)<EP&&p.y>0))
                mp[s[i]]++;
        }
        for (it = mp.begin(); it != mp.end(); it++)
        printf("%s\n", it->first.data());
        printf("\n");
    }
    return 0;
}


 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值