上海理工大学第二届“联想杯”全国程序设计邀请赛 - Experiment Class(几何+三分套三分)

Posted Frozen_Guardian

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了上海理工大学第二届“联想杯”全国程序设计邀请赛 - Experiment Class(几何+三分套三分)相关的知识,希望对你有一定的参考价值。

题目链接:点击查看

题目大意:在二维平面的第一象限中给出两条射线代表河流,再给出起点和终点,问从起点出发,至少经过两条河各一次后到达终点的最短路

题目分析:如果只有一条河的话就是初中数学的经典问题了,现在加上了两条河无非就是多了分类讨论,但是分类讨论写的那份代码过了 96% 多,还是算了吧

考虑三分套三分,当在某条河上确定了一个交点后,可以通过三分去寻找另一条河交点的最短路,所以是可行的

需要注意的是,因为整个矩阵的大小最大是 100 ∗ 100 100*100 100100 的,在此之中河流的最大长度实际上是对角线的长度,也就是 2 ∗ 100 \\sqrt{2}*100 2 100 的,所以三分的上界定到 200 200 200 倍的方向向量就可以啦

代码:

// Problem: Experiment Class
// Contest: NowCoder
// URL: https://ac.nowcoder.com/acm/contest/17574/E
// Memory Limit: 524288 MB
// Time Limit: 2000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

// #pragma GCC optimize(2)
// #pragma GCC optimize("Ofast","inline","-ffast-math")
// #pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include<iostream>
#include<cstdio>
#include<string>
#include<ctime>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<climits>
#include<queue>
#include<map>
#include<set>
#include<sstream>
#include<cassert>
#include<bitset>
#define lowbit(x) x&-x
using namespace std;
typedef long long LL;
typedef unsigned long long ull;
template<typename T>
inline void read(T &x)
{
    T f=1;x=0;
    char ch=getchar();
    while(0==isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    while(0!=isdigit(ch)) x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
    x*=f;
}
template<typename T>
inline void write(T x)
{
    if(x<0){x=~(x-1);putchar('-');}
    if(x>9)write(x/10);
    putchar(x%10+'0');
}
const int inf=0x3f3f3f3f;
const int N=1e6+100;
// `计算几何模板`
const double eps = 1e-8;
//`Compares a double to zero`
int sgn(double x){
	if(fabs(x) < eps)return 0;
	if(x < 0)return -1;
	else return 1;
}
struct Point{
	double x,y;
	Point(){}
	Point(double _x,double _y){
		x = _x;
		y = _y;
	}
	void input(){
		scanf("%lf%lf",&x,&y);
	}
	bool operator == (Point b)const{
		return sgn(x-b.x) == 0 && sgn(y-b.y) == 0;
	}
	bool operator < (Point b)const{
		return sgn(x-b.x)== 0?sgn(y-b.y)<0:x<b.x;
	}
	Point operator -(const Point &b)const{
		return Point(x-b.x,y-b.y);
	}
	//返回两点的距离
	double distance(Point p){
		return hypot(x-p.x,y-p.y);
	}
	Point operator +(const Point &b)const{
		return Point(x+b.x,y+b.y);
	}
	Point operator *(const double &k)const{
		return Point(x*k,y*k);
	}
	Point operator /(const double &k)const{
		return Point(x/k,y/k);
	}
}t1,t2,st,ed;
double cal(Point x,Point y) {
	return st.distance(x)+x.distance(y)+y.distance(ed);
}
double solve2(Point x) {
	Point l=Point(0,0),r=t2;
	while(l<r) {
		Point mid=l+(r-l)/3;
		Point mmid=r-(r-l)/3;
		if(cal(x,mid)<cal(x,mmid)) {
			r=mmid;
		} else {
			l=mid;
		}
	}
	return cal(x,l);
}
double solve1() {
	Point l=Point(0,0),r=t1;
	while(l<r) {
		Point mid=l+(r-l)/3;
		Point mmid=r-(r-l)/3;
		if(solve2(mid)<solve2(mmid)) {
			r=mmid;
		} else {
			l=mid;
		}
	}
	return solve2(l);
}
int main()
{
#ifndef ONLINE_JUDGE
//	freopen("data.in.txt","r",stdin);
//	freopen("data.out.txt","w",stdout);
#endif
//	ios::sync_with_stdio(false);
	t1.input(),t2.input(),st.input(),ed.input();
	t1=t1*200,t2=t2*200;
	double ans=solve1();
	swap(st,ed);
	ans=min(ans,solve1());
	printf("%.3f\\n",ans);
    return 0;
}

以上是关于上海理工大学第二届“联想杯”全国程序设计邀请赛 - Experiment Class(几何+三分套三分)的主要内容,如果未能解决你的问题,请参考以下文章

上海理工大学第二届“联想杯”全国程序设计邀请赛 - Experiment Class(几何+三分套三分)

上海理工大学第二届“联想杯”全国程序设计邀请赛 - Little Witch Academia(矩阵快速幂)

2011年全国大学生程序设计邀请赛(福州)

2021 ICPC全国邀请赛(西安)太原理工大学收获3枚奖牌

FZU - 2039 Pets (二分图匹配 2011年全国大学生程序设计邀请赛(福州))

“杭银理财”杯浙江工业大学大学生程序设计竞赛暨全国邀请赛 签到题9题