【2012百度之星 / 资格赛】I:地图的省钱计划

描述

百度地图有自己的一套坐标系(你可以把它看作一个笛卡尔坐标系),在这套坐标系里,一个标准单位为1km。而在这坐标系上针对地理信息进行标注的数据,大多数时候是通过购买的方式完成的。为了节约数据更新的成本,数据组里的鑫哥想出了一个好主意——自己测数据。
鑫哥按照他的预想开始实验;在每组试验中,鑫哥选取了三个已经被准确标注在百度地图的坐标系里的移动运营商的基站作为信号接收点(这里可以准确的得到信号的接收时间信息)。当信号接收点附近的用户手机签到时,三个信号接收点就会先后接收到这个信号,并可以准确的知晓接收到信号的时间(将第一个信号点接收到信号的时间记为0秒时刻)。由此,我们就可以确定用户手机签到的位置的在地图的准确坐标了。
现在已知以下数据:
1.三个信号接收点在百度地图坐标系中的具体坐标(x1,y1), (x2,y2), (x3,y3);
2.三个信号点得到用户发出的信号的时间t1, t2, t3(t1, t2, t3 ≥ 0),单位s; t1, t2, t3至少有一个数为0;
3.信号的转播速度C,单位m/s;
请帮助鑫哥写个程序,计算下用户发出信号的位置在百度地图坐标系内的坐标(这个点是唯一的)。

输入
输入包含多组数据,每组数据格式如下:
C
x1 y1 x2 y2 x3 y3
t1 t2 t3
最后一组数据为0,表示输入结束。
输出
针对每组测试数据,请先输出这个组的编号(第n组就是输出“Case n:”);然后换行输出信号发出点的坐标(x,y) 。x,y应该由空格分隔,并被舍入到小数点后第六位。
样例输入
1000
0 1 1 1 2 1
0 0.6 1.6
1000
0 0 0 1 1 0
0.4142135 0 0
1000
0 0 1 0 2 1
0 0.414213562373 1
1000
0 0 0 -1 0 1
0 0 1
1000
0 0 0 1 0 -1
0 1 0
1000
0 0 1 0 -1 0
0 1 0
1000
0 0 -1 0 1 0
0 0 1
100
0 0 0 1 1 0
0 10 10
0
样例输出
Case 1:
0.200000 1.000000
Case 2:
1.000000 1.000000
Case 3:
0.000000 1.000000
Case 4:
0.000000 -0.500000
Case 5:
0.000000 -0.500000
Case 6:
-0.500000 0.000000
Case 7:
-0.500000 0.000000
Case 8:
0.000000 0.000000

主要思路:这个题用三角函数来解方程会很方便的,通过将两个方程转化为一个三角函数方程,然后求角度cita和半径r就可以了(特别说明:最后那个分式中的分母部分中的l2、l3是没有平方的)。
【2012百度之星 / 资格赛】I:地图的省钱计划_第1张图片

实现代码:

#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
double x[4], y[4], t[4];

void solve(int i , int j , int k)
{
    double x2, y2, x3, y3, l2, l3 , sum , fai , cita , r , m , n;   //cita
    x2 = x[j] -x[i] , y2 = y[j] -y[i];
    x3 = x[k] -x[i] , y3 = y[k] -y[i];
    l2 = t[j] -t[i] , l3 = t[k] -t[i];
    m = x2*x2 + y2*y2 - l2*l2 , n = x3*x3 + y3*y3 - l3*l3;

    // 得到方程 a*sin(cita) + b*cos(cita) = -c
    double a = m*y3-n*y2 ;   //sin(cita)的系数
    double b = m*x3-n*x2 ;   //cos(cita)的系数
    double c = m * l3 - n * l2;
    // 得到方程 sin(cita+fai) = -c/(sqrt(a*a+b*b))
    fai = atan2(b, a) ;     //先求出角度fai
    sum = asin(- c/sqrt(a*a+b*b+1e-15));    //通过反正弦函数求出cita+fai的角度和
    
    cita = sum - fai;      // 此时cita是一个锐角
    if (abs(m)>abs(n))
        r = m/(l2 + x2 *cos(cita) + y2 * sin(cita))/2;
    else
        r = n/(l3 + x3 *cos(cita) + y3 * sin(cita))/2;
    if(r < 0)
    {
        sum = - sum + 3.141592653579;    //r<0,说明不能是锐角,应该是个钝角
        cita = sum - fai;
        if (abs(m)>abs(n))
            r = m/(l2 + x2 *cos(cita) + y2 * sin(cita))/2;
        else
            r = n/(l3 + x3 *cos(cita) + y3 * sin(cita))/2;
    }
    printf("%.6f %.6f\n", r * cos(cita) + x[i], r * sin(cita) + y[i]);
}
int main(void)
{
    int num = 1;
    double c;
    while(scanf("%lf", &c)!=EOF)
    {
        c/=1000;
        if (abs(c) < 1e-6)
            break;
        scanf("%lf %lf %lf %lf %lf %lf", x, y, x+1, y+1, x+2, y+2);
        scanf("%lf %lf %lf", t, t+1, t+2);
        printf("Case %d:\n", num++);
        t[0] *= c;
        t[1] *= c;
        t[2] *= c;
        solve(0, 1, 2);
    }
    return 0;
}



你可能感兴趣的:(c,百度,测试,手机)