codeforces #8D Two Friends (二分答案+计算几何)
来源:互联网 发布:社会调查知乎 编辑:程序博客网 时间:2024/06/01 08:52
题目链接;
点击打开题目链接
题意:
有两个人Alan 和Bob ,他们现在都在A 点,现在Bob 想去B 点,Alan 想先到C 点再去B 点。
要求Alan 走过的长度不能超过最短路长度+t1 ,Bob 走过的长度不能超过最短路长度+t2 ,求两人在一起最多走多久(分开后再汇合不算一起走)?
题解:
设Alan 最多走L1 ,Bob 最多走L2 ,注意还要加上t1 和t2 这两个差值。
首先如果Bob 能陪伴Alan 全程(即L2≥Distance(A,C)+Distance(C,B)) ,那么答案显然为min(L1,L2) 。此时他们一定是在Alan 到达C 之前分开的
否则两人分离时Bob 一定还没有经过C 点 ,这时显然不比一起回家更优。
容易发现答案是单调的,我们不妨二分答案x ,即Alan 和Bob 走距离为x 的相同路线后分开。
不妨设分离点为P ,当前二分到mid ,那么:
Distance(P,A)≤mid
Distance(P,C)≤L1−Distance(B,C)−mid
即:
设分离点为P ,那么点P 必须满足一下三个条件:
P 必须在以A 为圆心半径为x 的圆内,因为他们走的公共距离为x
P 必须在以B 为圆心半径为L2−x 的圆内,为了让Bob 在分开之后能及时返回B 点
P 必选在以C 为圆心半径为L1−x−BC 的圆内,因为Alan 在到达C 之后还要径直走回B 点。
所以如果三个圆相交,那么一定存在这样的点P 。
所以容易发现每个不等式中P 的范围都是一个圆 。
因此我们只需要判断三个圆是否有公共部分即可 。
判断三个圆是否相交:
三个圆两两相交是必要条件但不是充分条件。
因为可能会有这种情况:
在两两相交的前提下,如果有一个小圆内含在一个大圆内的话,那么这三个圆也是相交的。
否则,如果三个圆有公共部分,两两圆必然有1∼2 个交点。
如图:
考虑这三个圆的相交区域,它必然是由若干个圆弧组成的。
所以这块区域的关键点也一定是某两个圆的交点,枚举两两圆的共三组交点,如果有一个交点满足都在三个圆的圆内或圆上,那么这三个圆就是相交的。
我的是二分了200次。
AC代码:
//#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; 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; 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("%lf\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("%.4lf\n", l); } return 0;}
1 0
- codeforces #8D Two Friends 二分答案+计算几何
- codeforces #8D Two Friends (二分答案+计算几何)
- Codeforces 8D Two Friends 三分+二分+计算几何
- Codeforces 8D Two Friends
- CF 8D Two Friends (三分+二分)
- CF 8D Two Friends 【二分+三分】
- 计算几何 [二分答案]
- 【Codeforces Round 330 (Div 2)D】【计算几何 二分答案】Max and Bike 最小骑车距离使得圆上传感器很坐标位移为dis
- 【Educational Codeforces Round 2D】【计算几何 圆面积交 模板】Area of Two Circles' Intersection
- Educational Codeforces Round 2 D.Area of Two Circles' Intersection(计算几何)
- codeforces D. Multiplication Table 二分答案
- CodeForces 779D String Game【二分答案】
- Codeforces 689D Friends and Subsequences(二分+RMQ)
- Codeforces 689D Friends and Subsequences(二分+RMQ)
- Codeforces 689D Friends and Subsequences(RMQ+二分)
- Codeforces 689D Friends and Subsequences (RMQ+二分)
- [Codeforces 689D] Friends and Subsequences (二分+稀疏表)
- Codeforces 689D Friends and Subsequences(二分+RMQ)
- WIN32多线程
- JQuery中的回调对象
- 网上图书商城视频教程day06
- CSS中的视觉格式化模型
- TCP/IP详解--发送ACK和RST的场景
- codeforces #8D Two Friends (二分答案+计算几何)
- 实验五
- jQuery中基本的动画方法
- MFC多线程
- Mac快捷键
- 从三栏自适应宽度布局到css布局的讨论
- Qt5.5.1编译出来的程序出现libgcc_s_dw2-1.dll的解决方案
- 软件行业 职位 英文简称
- swift3.1 (8)Enumerations,Classes,Structures,Properties and methods(部分精华)