上海理工大学第二届“联想杯”全国程序设计邀请赛 - Experiment Class(几何+三分套三分)
Posted Frozen_Guardian
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了上海理工大学第二届“联想杯”全国程序设计邀请赛 - Experiment Class(几何+三分套三分)相关的知识,希望对你有一定的参考价值。
题目链接:点击查看
题目大意:在二维平面的第一象限中给出两条射线代表河流,再给出起点和终点,问从起点出发,至少经过两条河各一次后到达终点的最短路
题目分析:如果只有一条河的话就是初中数学的经典问题了,现在加上了两条河无非就是多了分类讨论,但是分类讨论写的那份代码过了 96% 多,还是算了吧
考虑三分套三分,当在某条河上确定了一个交点后,可以通过三分去寻找另一条河交点的最短路,所以是可行的
需要注意的是,因为整个矩阵的大小最大是 100 ∗ 100 100*100 100∗100 的,在此之中河流的最大长度实际上是对角线的长度,也就是 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(矩阵快速幂)
2021 ICPC全国邀请赛(西安)太原理工大学收获3枚奖牌