列表

详情


NC19766. New Game!

描述

Eagle Jump公司正在开发一款新的游戏。Hifumi Takimoto作为其中的员工,获得了提前试玩的机会。现在她正在试图通过一个迷宫。
这个迷宫有一些特点。为了方便描述,我们对这个迷宫建立平面直角坐标系。迷宫中有两条平行直线 L1:Ax+By+C1=0, L2:Ax+By+C2=0,还有 n 个圆 。角色在直线上、圆上、园内行走不消耗体力。在其他位置上由S点走到T点消耗的体力为S和T的欧几里得距离。
Hifumi Takimoto想从 L1 出发,走到 L2 。请计算最少需要多少体力。

输入描述

第一行五个正整数 n,A,B,C1,C2 (1≤ n ≤ 1000, -10000 ≤ A,B,C1,C2 ≤ 10000),其中 A,B 不同时为 0。
接下来 n 行每行三个整数 x,y,r(-10000 ≤ x,y ≤ 10000, 1≤ r ≤ 10000) 表示一个圆心为 (x,y),半径为 r 的圆。

输出描述

仅一行一个实数表示答案。与正确结果的绝对误差或者相对误差不超过 10-4 即算正确。

示例1

输入:

2 0 1 0 -4
0 1 1
1 3 1

输出:

0.236068

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 7ms, 内存消耗: 492K, 提交时间: 2018-10-01 14:26:47

#include<bits/stdc++.h>
using namespace std;
const int INF=1e9;
int n,a,b,c1,c2;
struct Circle
{
	int x,y,r;
	double d;
};
Circle c[1005];
bool cmp(Circle &c1,Circle &c2)
{
	return c1.d<c2.d;
}
double dist(int x,int y,int c)
{
	return abs((double)a*x+b*y+c)/(sqrt(a*a+b*b));
}
double Cdist(Circle &c1,Circle &c2)
{
	double dd=sqrt((c1.x-c2.x)*(c1.x-c2.x)+(c1.y-c2.y)*(c1.y-c2.y));
	return max(0.0,dd-c1.r-c2.r);
}
double f[1005];
int main()
{
	ios::sync_with_stdio(false);
	cin>>n>>a>>b>>c1>>c2;
	double ans=abs((double)c1-c2)/(sqrt(a*a+b*b));
	for(int i=1;i<=n;i++)
	{
		cin>>c[i].x>>c[i].y>>c[i].r;
		c[i].d=max(dist(c[i].x,c[i].y,c1)-c[i].r,0.0);
	}
	sort(c+1,c+n+1,cmp);
	for(int i=1;i<=n;i++)
	{
		f[i]=c[i].d;
		for(int j=1;j<i;j++) f[i]=min(f[i],f[j]+Cdist(c[i],c[j]));
		ans=min(ans,f[i]+max(dist(c[i].x,c[i].y,c2)-c[i].r,0.0));
	}
	cout<<setiosflags(ios::fixed)<<setprecision(6)<<ans<<endl;
 } 

C++11(clang++ 3.9) 解法, 执行用时: 25ms, 内存消耗: 8160K, 提交时间: 2020-02-27 20:55:14

#include<bits/stdc++.h>
using namespace std;
double g[1005][1005],d[1005];
int n,a,b,c1,c2,x[1005],y[1005],r[1005],i,j,k;
bool v[1005];
int main()
{
	cin>>n>>a>>b>>c1>>c2;
	for(i=1;i<=n;i++) cin>>x[i]>>y[i]>>r[i];
	for(i=1;i<=n;i++)
	{
		for(j=i+1;j<=n;j++)
		g[i][j]=g[j][i]=max(sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]))-r[i]-r[j],0.0);
		g[0][i]=g[i][0]=max(fabs(a*x[i]+b*y[i]+c1)/sqrt(a*a+b*b)-r[i],0.0);
		g[n+1][i]=g[i][n+1]=max(fabs(a*x[i]+b*y[i]+c2)/sqrt(a*a+b*b)-r[i],0.0);
		
	}
	g[0][n+1]=g[n+1][0]=fabs(c1-c2)/sqrt(a*a+b*b);
	for(i=1;i<=n+1;i++) d[i]=1e15;
	for(i=0;i<=n;i++)
	{
		for(j=0,k=-1;j<=n+1;j++)
		if(!v[j]&&(!~k||d[j]<d[k])) k=j;
		v[k]=1;
		for(j=0;j<=n+1;j++) d[j]=min(d[j],d[k]+g[k][j]);
	}
	printf("%.6lf\n",d[n+1]);
	return 0;
}

上一题