Codeforces 8D Two Friends 三圆交集是否为非空集合 二分 旋转x轴

讲述了两位朋友在看完电影后如何规划他们的回家路线,以便能够一起讨论电影并保持一定距离范围内的故事。考虑到各自家的距离限制,他们需要找到一条最优路径。

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

D. Two Friends
time limit per test
1 second
memory limit per test
64 megabytes
input
standard input
output
standard output

Two neighbours, Alan and Bob, live in the city, where there are three buildings only: a cinema, a shop and the house, where they live. The rest is a big asphalt square.

Once they went to the cinema, and the film impressed them so deeply, that when they left the cinema, they did not want to stop discussing it.

Bob wants to get home, but Alan has to go to the shop first, and only then go home. So, they agreed to cover some distance together discussing the film (their common path might pass through the shop, or they might walk circles around the cinema together), and then to part each other's company and go each his own way. After they part, they will start thinking about their daily pursuits; and even if they meet again, they won't be able to go on with the discussion. Thus, Bob's path will be a continuous curve, having the cinema and the house as its ends. Alan's path — a continuous curve, going through the shop, and having the cinema and the house as its ends.

The film ended late, that's why the whole distance covered by Alan should not differ from the shortest one by more than t1, and the distance covered by Bob should not differ from the shortest one by more than t2.

Find the maximum distance that Alan and Bob will cover together, discussing the film.

Input

The first line contains two integers: t1, t2 (0 ≤ t1, t2 ≤ 100). The second line contains the cinema's coordinates, the third one — the house's, and the last line — the shop's.

All the coordinates are given in meters, are integer, and do not exceed 100 in absolute magnitude. No two given places are in the same building.

Output

In the only line output one number — the maximum distance that Alan and Bob will cover together, discussing the film. Output the answer accurate to not less than 4 decimal places.

Examples
input
0 2
0 0
4 0
-3 0
output
1.0000000000
input
0 0
0 0
2 0
1 0
output
2.0000000000
//#pragma comment(linker, "/STACK:102400000,102400000")
//#include <bits/stdc++.h>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <vector>
#include <map>
#include <cmath>
#include <queue>
#include <set>
#include <bitset>
#include <iomanip>
#include <list>
#include <complex>
#include <stack>
#include <utility>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef vector<int> vi;
const double eps = 1e-8;
const int INF = 1e9+7;
const ll inf =(1LL<<62) ;
const int MOD = 1e9 + 7;
const ll mod = (1LL<<32);
const int N =1e6+6;
const int M=100010;
const int maxn=1001;
#define mst(a) memset(a, 0, sizeof(a))
#define M_P(x,y) make_pair(x,y)
#define pi acos(-1.0)
#define in freopen("in.txt","r",stdin)
#define rep(i,j,k) for (int i = j; i <= k; i++)
#define per(i,j,k) for (int i = j; i >= k; i--)
#define lson x << 1, l, mid
#define rson x << 1 | 1, mid + 1, r
const int lowbit(int x) { return x&-x; }
int read(){ int v = 0, f = 1;char c =getchar();
while( c < 48 || 57 < c ){if(c=='-') f = -1;c = getchar();}
while(48 <= c && c <= 57) v = v*10+c-48, c = getchar();
return v*f;}
#define point complex<double>
double t1, t2;
point cinema, shop, house;

void readpoint(point &p)
{
  double x, y;
  scanf("%lf %lf", &x, &y);
  p = point(x, y);
}

bool inter(point a, double r_a, point b, double r_b, point c, double r_c) //以c为主圆求a b焦点判相交
{
  if (abs(c - a) <= r_a && abs(c - b) <= r_b) return true;
  //if (r_a + r_b < abs(b - a) || abs(b-a) + r_a < r_b || abs(b-a) + r_b < r_a) return false; 此处比较的精度不够会严重放大至二分的结果!!!!!
  b -= a;
  c -= a; //以a为原点
  point r = point(b.real() / abs(b), b.imag() / abs(b)); //将x轴正方向置为b
  b /= r;
  c /= r;
  double d = (r_a * r_a - r_b * r_b + abs(b) * abs(b)) / (2 * abs(b));
  double h = sqrt(max(r_a * r_a - d * d, 0.0));
  if (abs(h * h + (d - abs(b)) * (d - abs(b))) - r_b * r_b > eps) return false;//这行本地ac 测评ac
  if (abs(point(d, h) - c) <= r_c || abs(point(d, -h) - c) <= r_c) return true;
  return false;
}

bool check(point a, double r_a, point b, double r_b, point c, double r_c) //判断三圆是否相交
{
  if (r_a <= eps || r_b <= eps || r_c <= eps) return false; //有空集
  r_a = max(r_a, 0.0);
  r_b = max(r_b, 0.0);
  r_c = max(r_c, 0.0);
  if (inter(a, r_a, c, r_c, b, r_b)) return true;
  if (inter(b, r_b, a, r_a, c, r_c)) return true;
  if (inter(c, r_c, b, r_b, a, r_a)) return true;
  return false;
}

int main()
{
  scanf("%lf %lf", &t1, &t2);
  readpoint(cinema); //cinema
  readpoint(house); //house
  readpoint(shop); //shop

  if (abs(shop - cinema) + abs(house - shop) <= abs(cinema - house) + t2)//Alan <= Bob + t2
  {
    printf("%f\n", min( abs(cinema - house) + t2, abs(shop - cinema) + abs(house - shop) + t1));
  }
  else
  {
    double l, r, mid;
    l = 0;
    r = min( abs(cinema - house) + t2, abs(shop - cinema) + abs(house - shop) + t1);

    for(int i=1;i<=200;i++)
    {
      mid = (r + l) / 2;
      if (check(cinema, mid, shop, abs(shop - cinema) + t1 - mid, house, abs(house - cinema) + t2 - mid)){
        l = mid;
      }
      else {
        r = mid;
      }
    }
    printf("%f\n", l);
  }
  return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值