如下图所示的螺旋折线经过平面上所有整点恰好一次。
对于整点 (X,Y),我们定义它到原点的距离dis(X,Y) 是从原点到(X,Y)的螺旋折线段的长度。
例如 dis(0,1)=3,dis(−2,−1)=9
给出整点坐标 (X,Y),你能计算出dis(X,Y) 吗?
输入格式
包含两个整数 X,Y。
输出格式
输出一个整数,表示 dis(X,Y)。
数据范围
−10^9≤X,Y≤10^9
输入样例:
0 1
输出样例:
3
分析:刚开始接触这道题时没有明确的思路,然后就计算了一部分点尝试找规律,标注如下图(此图不是本人所画):
发现了位于图中对角线部分的点距离存在一定的规律,都已经标注在图中,下面容易想到的就是我们需要用已经发现的规律来解决本道题,也就是说我们要把所有点与位于对角线上的点建立一种特殊的关系,这样就方便我们进行计算了,下面直接说一下怎么建立特殊的点与普通的点之间的关系吧:
第一区域:
随便给出一个点(x,y),这个点最上边的点就是这个图的右上方的点,我们可以得到和这个点在同一竖线上最上边的点离原点的距离为(2*y-1)*2*y,然后我们只需要加上两个点之间的横向距离即可,因为最左边这个点为(-y,y)(他与给定点y相同,又因为本身具有y=-x的性质),所以距离为x-(-y),所以总地距离就是(2*y-1)*2*y+x-(-y)
第二区域:
随便给出一个点(x,y),这个点最左边的点就是这个图的左上方的点,我们可以得到和这个点在同一直线上最左边的点离原点的距离为(2*x)*(2*x),然后我们只需要加上两个点之间的纵向距离即可,因为最上边这个点为(x,x)(他与给定点x相同,又因为本身具有y=x的性质),所以距离为x-y,所以总地距离就是(2*x)*(2*x)+x-y
第三区域:
随便给出一个点(x,y),这个点最右边的点就是这个图的右下方的点,我们可以得到和这个点在同一直线上最右边的点离原点的距离为(2*(-y))*(2*(-y)+1),然后我们只需要加上两个点之间的横向距离即可,因为最右边这个点为(-y,y)(他与给定点y相同,又因为本身具有y=-x的性质),所以距离为-y-x,所以总地距离就是(2*(-y))*(2*(-y)+1)-y-x
第四区域:
随便给出一个点(x,y),这个点最下边的点就是这个图的左下方的点,我们可以得到和这个点在同一直线上最下边的点离原点的距离为(2*(-x)-1)*(2*(-x)-1),然后我们只需要加上两个点之间的纵向距离即可,因为最下边这个点为(x,x+1)(他与给定点x相同,又因为本身具有y=x+1的性质),所以距离为y-x-1,所以总地距离就是(2*(-x)-1)*(2*(-x)-1)+y-x-1
分析到这就结束了,实现就比较容易了,下面是代码:
#include<cstdio>
#include<iostream>
#include<cstring>
#include<vector>
#include<algorithm>
#include<map>
#include<cmath>
#include<queue>
using namespace std;
typedef long long ll;
int main()
{
ll x,y;
cin>>x>>y;
if(abs(x)<=y)//在(1)区域
cout<<(2*y-1)*(2*y)+x-(-y)<<endl;
else if(abs(y)<=x)//在(2)区域
cout<<(2*x)*(2*x)+x-y<<endl;
else if(abs(x)<=abs(y)+1&&y<0)//在(3)区域
cout<<(2*(-y))*(2*(-y)+1)-y-x<<endl;
else//在(4)区域
cout<<(2*(-x)-1)*(2*(-x)-1)+y-x-1<<endl;
return 0;
}