如下图所示的螺旋折线经过平面上所有整点恰好一次。
对于整点(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
资源约定:
峰值内存消耗(含虚拟机) < 256M
CPU消耗 < 1000ms
假设要求的坐标是$(x,y)$,那么根据上面的图就可以把$(x,y)$所在的层数确定,$layer = max(abs(x),abs(y))$,确定层数以后,前面所有层的线段和就确定了,假设$(x,y)$在第$n$层,那么前面$n-1$层正方形线段和就是$4\times (n + 1)\times n$
接着再看$(x,y)$这个坐标是第$n$层的第几个。我们可以认为第$i$层的起始点坐标是$(-i, -i + 1$,那么求得$(x,y)$到起始点之间的距离之后还要加上1
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner cin = new Scanner(System.in);
long x = cin.nextLong();
long y = cin.nextLong();
if (x == 0 && y == 0)
System.out.println(0);
else {
long layer = Math.max(Math.abs(x), Math.abs(y));
long sum = (layer * (layer - 1)) << 2;
sum += cnt(x, y, layer);
System.out.println(sum);
}
}
static long cnt(long x, long y, long layer) {
long startx = -layer;
long starty = -layer + 1;
if (x >= startx && y == layer) { // 处于正方形的上边
return Math.abs(x - startx) + Math.abs(y - starty) + 1;
} else if (x == startx && y >= starty) { // 处于起点上方的位置
return Math.abs(x - startx) + Math.abs(y - starty) + 1;
} else if (x == -startx) { // 处于正方形的右边
long segement = Math.abs(y - layer);
return segement + cnt(x, layer, layer);
} else { // 处于起点下方位置
long segement = Math.abs(x - layer);
return segement + cnt(layer, y, layer);
}
}
}
貌似有地方写错了 假设在第四层 前面正方形的周长是 24+44+64=48 所以你的表达式貌似写错了 应该是4n*(n-1)
n(n-1)4 = (n (n - 1)) 4 = (n * (n - 1)) << 2
这个4n(n-1)是怎么推出来的鸭@(小乖)
找规律,玄学
等差数列求和,看出来了@(哈哈)