MENU

第九届蓝桥杯 Java B—— 螺旋折线

March 22, 2019 • Read: 8507 • 算法阅读设置

如下图所示的螺旋折线经过平面上所有整点恰好一次。
对于整点 (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);
  • }
  • }
  • }
Archives Tip
QR Code for this page
Tipping QR Code
Leave a Comment

5 Comments
  1. 西塔里 西塔里

    貌似有地方写错了 假设在第四层 前面正方形的周长是 24+44+64=48 所以你的表达式貌似写错了 应该是 4n*(n-1)

    1. mathor mathor

      @西塔里 n(n-1)4 = (n (n - 1)) 4 = (n * (n - 1)) << 2

  2. jay jay

    这个 4n (n-1) 是怎么推出来的鸭 @(小乖)

    1. mathor mathor

      @jay 找规律,玄学

    2. jay jay

      @jay 等差数列求和,看出来了 @(哈哈)