杭电OJ2073 无限的路(已AC,超详细解释,适合初学者)

题目就不贴了,就放个图方便大家打草稿示意在这里插入图片描述
先别急着看代码,把思路捋清楚。
##首先题目是求两点的距离,我们可以先求出第一个点到原点的距离,再求出第二个点到原点的距离,然后两者相减即可,重要的是求出距离公式,就ok了。(注:这里的到原点距离是指中途所经过的所有线段的长度和,不是直接求到原点距离哦233别搞错了)

##递推过程:可以发现,图中的线段长度除了(0,0)->(0,1)长度是1,其他的只有两种,一种是斜率为-1的线段,一种是斜率为-2的线段,分别可以用m=sqrt((i-1) * (i - 1)+(i-1) * (i-1))和n=sqrt(i * i+(i-1) * (i-1))来表示,因为(0,0)->(0,i)的距离可以表示为(0,0)->(0,i-1)+(0,i-1)->(i-1,0)+(i-1,0)->(0,i),自己看图走一遍就懂了,用f(i)表示(0,0)->(0,i)的距离,则(0,0)->(0,i-1)的距离为f(i-1),其中f(1)=1,而(0,i-1)->(i-1,0)即为m,(i-1,0)->(0,i)即为n,于是每个y轴上的点(0,i)到原点距离的递推关系式就出来了:
f(i)=f(i-1)+m+n ;f(1)=1
再观察图中的点,发现不在坐标轴上的点都有一个特点,就是同一条线上的x+y相等
所以如果要求的是(x,i)到原点的距离的话,等价于求(0,x+i)到原点的距离即f(x+i)再加上x*sqrt(2.0)即可(观察图就可以得到,横坐标每增加1,长度增加根号2,别说你看不出来233)实在不懂就举个例子,就明白了,实践出真知。

#综上:点(x,y)到原点的距离公式为d=f(x+y)+x*sqrt(2.0)
公式出来了就直接套用就可以了,代码没什么难的,AC代码如下

#include<stdio.h>
#include<math.h>
#include<string.h>
double f[210];
double dabiao()//有公式了就先打表一下,就是提前计算好,下面代入点(x,y)的时候可以直接调用
{
	f[1]=1;
	for(int i=2;i<=200;i++)
	{
		double m,n;
		m=sqrt((i-1)*(i-1)+(i-1)*(i-1));
		n=sqrt(i*i+(i-1)*(i-1));
		f[i]=f[i-1]+m+n;
	}//有不明白的见上面解析
	return 0;
}

double distance(int x,int y)
{
	double d=0;
	d=f[x+y]+x*sqrt(2.0);
	return d;
}//点(x,y)到原点的距离公式

int main()
{
	int x1,y1,x2,y2,n;
	double d1,d2,d;
	dabiao();
	while(scanf("%d",&n)!=EOF)
	{
	while(n--)
	{
		scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
		d1=distance(x1,y1);
		d2=distance(x2,y2);
		d=d1-d2;
		if(d<0) d=-d;
		printf("%.3lf\n",d);
	}
	}
	return 0;
}

这次文字讲解很多,虽然很啰嗦,但是自己还是很用心的讲到每一个点了,因为自己当时也是想了好久才想通,所以希望可以尽可能的清楚地讲解给大家,同时也算是巩固一下自己吧。

  • 14
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

HDU-五七小卡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值