SPOJ BLMIRINA 计算几何

本文介绍了一个几何问题,即从原点出发的弓箭如何击中以(x,y)为中心,半径为r的圆上的最远点。通过二分查找算法确定最佳射击位置,并提供了完整的C++实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Archery Training


Mirana is an archer with superpower. Every arrow she shoots will get stronger the further it travels. Mirana is currently on the way to warzone.

Since the road is still a long way, Mirana remembers about when she's still in training. In each of her training, Mirana stands on the (0,0) point in a cartesian scale. From that point, she must shoot a circle centered in (x,y) with radius r. Everything happens in z=0.

To maximize the arrow's power, Mirana must shoot the furthest point of the enemy possible. Her arrow travels at the speed of light and will instantly stops the moment it touches the target. On the target, determine the coordinate point that Mirana has to shoot to get maximum power. If multiple coordinate exists, choose the one with the lower x value.

Input

First line is T, number of training (T < 100000). Next T lines each contains 3 space separeted integers x, y, and r for each training (1 < r < x,y < 1000)

Output

For each training, output a line containing the coordinate of the arrow's destination separated by space. Output until 6 digit after decimal point.

Example

Input:
3
1 1 1
2 2 1
4 5 2 
Output:
0.000000 1.000000
1.088562 2.411438
2.126155 5.699076

题意:从原点发射一颗子弹,当子弹遇到障碍物的时候就会停下。
障碍物为一个圆心为(x, y), 半径为r的圆。
问子弹停下后,距离原点最远的位置坐标是多少,多个时答案输出x坐标最小的那个。


题解:最远的点,那肯定是切线。

我们可以二分x来确定r

判断条件是当前(x,y)与r的距离来二分x


#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<deque>
#include<map>
#include<cmath>
using namespace std;
typedef long long ll;
int main(){  
    int t;
    scanf("%d",&t);
    while(t--){
    	double x,y,d;
    	scanf("%lf%lf%lf",&x,&y,&d);
        double l=0,r=x;
        double dis=x*x+y*y-d*d;
        for(int i=1;i<=100;i++){
            double m=(l+r)/2;
            if((m-x)*(m-x)+(sqrt(dis-m*m)-y)*(sqrt(dis-m*m)-y)>d*d)l=m;
            else r=m;
        }
        printf("%.6f %.6f\n",l,sqrt(dis-l*l));
    }
    return 0;  
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值