1. 程式人生 > >第九屆藍橋杯 Java語言B組 第七題 螺旋折線

第九屆藍橋杯 Java語言B組 第七題 螺旋折線

題目:螺旋折線

如圖p1.pgn所示的螺旋折線經過平面上所有整點恰好一次。
對於整點(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
90000000
【輸出格式】
輸出dis(X, Y)

【輸入樣例】
0 1

【輸出樣例】
3

資源約定:
峰值記憶體消耗(含虛擬機器) < 256M
CPU消耗 < 1000ms

請嚴格按要求輸出,不要畫蛇添足地列印類似:“請您輸入…” 的多餘內容。

所有程式碼放在同一個原始檔中,除錯通過後,拷貝提交該原始碼。
不要使用package語句。不要使用jdk1.7及以上版本的特性。
主類的名字必須是:Main,否則按無效程式碼處理。

1. 思路

看到網上很多人用的方法都是去算邊,算點,感覺這種方法比較麻煩,而且容易出錯

我的方法是去算正方形的長度,仔細觀察這張圖,我們只要把左下的一條邊順時針旋轉90°,就能得到一個矩形

在這裡插入圖片描述

然後我們只要操作兩個步驟:

1. 計算這個點之前的所有正方形


2. 計算這個點所在的幾條邊

2. 設計步驟

我們舉個例子,假設我們要計算point(-1, 2)這個點
第一個步驟相當簡單,我們發現每個正方形都是一個等差數列
這個數列是8, 16, 24, 32....
所以我們拿前n項和公式來算就行,注意算這個點之前所在所有正方形的和

第二個步驟需要一些技巧,我們發現,我們將左下的邊旋轉之後,對應著的點是(-1, -1), (-2, -2), (-3, -3)....(-n, -n)
所以我們從這個點開始,計算這個點到point的邊距離

最後我們加上兩個步驟算出來的距離,就得到了答案

3. 程式碼

package eighth.
provincial.competition; import java.util.Scanner; public class G { public static void main(String[] args) { Scanner in = new Scanner(System.in); long X = in.nextLong(); long Y = in.nextLong(); // 判斷所在點所在的正方形 long n = Math.max(Math.abs(X) , Math.abs(Y)); // 1. 之前正方形的長度和 long Sn = 4*(n-1)*n; // 2. 計算點(-n, -n) 到點(X, Y)的距離, 考慮清楚情況 long sum = 0; long px = -n, py = -n; long d1 = X-px, d2 = Y-py; if (Y > X) { sum += (d1+d2); } else { sum += (8*n-d1-d2); } System.out.println(sum + Sn); } }