题目
如下图所示的螺旋折线经过平面上所有整点恰好一次。
对于整点 (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)。
数据范围
−109≤X,Y≤109
输入样例:
0 1
输出样例:
3
题解:
看到图,首先想到最终答案与目标点所在的圈数有关,但是螺旋形还是有点不规则,所以我们可以通过旋转一些线段来转换这个图形,变成以下规则的同心正方形。
这时候起点从原点变成了(-1,-1),同理第n圈的起点是(-n,-n)。于是可以找规律求解,假如目标点在第k圈,则1~k-1圈的路程是等差数列求和,剩下第k圈不足一圈的部分,判断下目标点在哪个象限,计算下就好。
#include<bits/stdc++.h>
#define ll long long
using namespace std;
inline ll cal1(ll num){ // 所有完整圈的路程和
if(num <= 1)
return 0;
num--;
ll res = num * 8 + (num*(num-1)) * 4;
return res;
}
inline ll cal2(ll num, ll x, ll y){ // 最后一圈的路程
ll res = 0;
if(x == -num)
res += num + y;
else if(y == num)
res += num * 2 + num + x;
else if(x == num)
res += num * 4 + num - y;
else if(y == -num)
res += 6 * num + num - x;
return res;
}
int main(){
ll x, y;
ll dis = 0;
cin >> x >> y;
ll num = max(abs(x), abs(y)); // 圈数
dis = cal1(num) + cal2(num, x, y);
cout << dis << endl;
return 0;
}