试题 历届真题 螺旋折线【第九届】【省赛】【B组】-CSDN博客

70 阅读2分钟

 

 在看到该题的第一眼我想到的是之前做过的一道题目(1条消息) 算法入门之蛇形填数_ZZZWWWFFF_的博客-CSDN博客

然而我在经过利用“蛇形填数”的思想来尝试做这道题后发现难以实现(坐标与数组下标难以对上),经过将近1个小时的努力我还是做不出来~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

下面给出题解

 首先我们注意观察题目给的图,我们可以发现每次顺时针旋转一小段线段,我们就可以得到上面这个图,我们不妨假设我们现在需要求(1,2)这个点,那么我们画图

我们发现我们要求的距离由这个点之前的正方形边长加上图中蓝线的距离之和组成,而这段蓝线的距离恰好就是(1,2)到(-2,-2)这个点的x距离与y距离分别相加得到即1-(-2)+2-(-2)=7

顺着这样的思路,我们不难发现还有另外一种情况,即当我们要求的点在y=x这条直线的下面时

我们举个例子:求(2,-1)

 

 那么,我们要求的距离就变成这个点之前的正方形的周长+蓝线长,我们不难发现,蓝线长=这个点所在的正方形周长-绿线长,而绿线长恰好=这个点到(-2,-2)的x距离+y距离!!!!!!!

这样我们将上面的思路转换成代码:

#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
int main()
{
	ll x,y,n,Sn,px,py,ans=0;
	cin>>x>>y;
	n=max(abs(x),abs(y));//判断(x,y)所在的正方形
	Sn=(n-1)*4*n;//利用数学等差数列知识 8 16 24 32
	
	ll dx,dy;
	px=py=-n;
	dx=x-px;
	dy=y-py;
	if(y>=x)
	{
		ans+=(dx+dy);	
	 } 
	else
	{
		ans+=(n*8-(dx+dy));
	}
	cout<<ans+Sn<<endl;
	return 0;
}