首页 > 其他 > 详细

Chris and Road CodeForces - 703C 【几何 贪心 二分】

时间:2020-05-06 23:28:46      阅读:96      评论:0      收藏:0      [点我收藏+]

题目链接

CF703C

题意

给你一个凸多边形的车,一条街宽w(y=0,y=w之间),你站在(0,0)可以以u速度往上走,车可以以v的速度往x轴负方向走,问你最少要多久你才能跨过这条街。在这个多边形的边上和顶点上不算被撞。
技术分享图片

思路

  • 两个都在移动,那就换一种坐标系,看作是人在两个方向都可以移动,可以以v的速率向x轴正方向移动,也可以以u的速率向y轴正方向移动。
  • 合成速度 V ,如果可以一直移动不被车撞的话,那么这条斜率为(u/v)的直线不会穿过多边形内部。
  • 所以现在的目标是,找到x轴上那个开始可以随意以合成速度 V行走的点x。总的时间就是 \(\frac{x}{v}+\frac{w}{u}\)
  • 如何判断有没有穿过多边形内部?
    • 第一种情况,凸多边形所有的点都在这条线的右下方:这样的话从(0,0)开始走最快,不需要找点了,时间为\(w/u\)
    • 第二种情况,凸多边形所有的点都在这条线的左上方:通过二分找点在哪。
    • 如何判断所有的点是不是都在一边:高中数学线性规划里就有用到,\(y_0-k*x_0+k*x\)是不是都是正或者负。
  • 注意事项:
    • 由于是double,所以判断大小要用eps。
    • eps太小了的话会tle ??

代码

#include<bits/stdc++.h>
using namespace std;
const int MAXN=10005;
const double eps=1e-6;
int n;
double w,v,u;
typedef pair<double,double> pa;
pa a[MAXN];
double k;
bool judge(double x){
	int tot1=0,tot2=0;
	for(int i=1;i<=n;i++){
		if(a[i].first-k*a[i].second+k*x<eps)	tot1++;
		else tot2++;
		if(tot1&&tot2) return false;
	}
	return true;
}
int main(){
	scanf("%d%lf%lf%lf",&n,&w,&v,&u);
	double mx=0;
	for(int i=1;i<=n;i++){
		scanf("%lf%lf",&a[i].second,&a[i].first);
		mx = mx<a[i].second?a[i].second:mx;
	} 
	k=u/v; 
	double l=0,r=mx;
	if(judge(0.0)){
		printf("%.10lf\n",w/u);
		return 0;
	}
	double mid,ans;
	while(r-l>eps){
		mid=(r+l)/2;
		if(judge(mid)){
			r=mid;	
		}
		else l=mid;
	} 
	printf("%.10lf\n",mid/v+w/u);
	return 0;
}

Chris and Road CodeForces - 703C 【几何 贪心 二分】

原文:https://www.cnblogs.com/xuwanwei/p/12835408.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!