题目如下
标题:螺旋折线
如图p1.png所示的螺旋折线经过平面上所有整点恰好一次。
对于整点(X, Y),我们定义它到原点的距离dis(X, Y)是从原点到(X, Y)的螺旋折线段的长度。
例如dis(0, 1)=3, dis(-2, -1)=9
给出整点坐标(X, Y),你能计算出dis(X, Y)吗?
【输入格式】
X和Y
对于40%的数据,-1000 <= X, Y <= 1000
对于70%的数据,-100000 <= X, Y <= 100000
对于100%的数据, -1000000000 <= X, Y <= 1000000000
【输出格式】
输出dis(X, Y)
【样例输入】
0 1
【样例输出】
3
问题的突破口如下图:
找寻规律不难发现在直线y=x+1且在第三象限三的点均为平方数
所以在解这题的时候我们可以先定位到这个平方数,然后再根据在这个平方数进行推算
unsigned long long ans=0;
int n,m,x,y;
cin>>n>>m;
int cengshu=max(abs(n),abs(m));
ans=ans+(cengshu*2-1)*(cengshu*2-1);
于是ans被定位到了那个平方数
然后针对点在这层的左上右下方位进行处理
下面拿右边上作为句子举例:
else if(n>0&&abs(n)==cengshu) //判断在右边上
{
ans=ans+(2*cengshu-1)+2*cengshu; //加上左边和上边的距离
y=n-m; //看右边的距离有多长
ans+=y;
}
下面附上完整代码:
(本人一直从0测试到了49,应该没啥问题了)
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
const int N=100003;
int main()
{
unsigned long long ans=0;
int n,m,x,y;
cin>>n>>m;
int cengshu=max(abs(n),abs(m));
ans=ans+(cengshu*2-1)*(cengshu*2-1);
//找规律可知y=x+1的第三象限部分的dis是有规律的,为(abs(x)*2-1)^2。得到输入之后直接定位到这个位置
if(n==0&&m==0) ans=0;
else if(n<0&&n==m) ans=((2*cengshu)+1)*((2*cengshu)+1)-1;
else if(n<0&&abs(n)==cengshu) //左边
{
y=m+(abs(n)-1);
ans+=y;
}
else if(m>0&&abs(m)==cengshu) //上边
{
ans+=(2*cengshu-1);
x=n+m;
ans+=x;
}
else if(n>0&&abs(n)==cengshu) //右边
{
ans=ans+(2*cengshu-1)+2*cengshu;
y=n-m;
ans+=y;
}
else if(m<0&&abs(m)==cengshu) //下边
{
ans=ans+(2*cengshu-1)+2*cengshu+2*cengshu;
x=abs(m)-n;
ans+=x;
}
cout<<ans;
return 0;
}