你好呀,我是灰小猿,一個超會寫bug的程式猿!
歡迎大家關注我的專欄“每日藍橋”,該專欄的主要作用是和大家分享近幾年藍橋杯省賽及決賽等真題,決議其中存在的演算法思想、資料結構等內容,幫助大家學習到更多的知識和技術!
標題:螺旋折線
如下圖所示的螺旋折線經過平面上所有整點恰好一次,
對于整點 (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),
資料范圍
?10^9≤X,Y≤10^9
輸入樣例:
0 1
輸出樣例:
3
資源約定: .
峰值記憶體消耗(含虛擬機) < 256M
CPU消耗< 1000ms
請嚴格按要求輸出,不要畫蛇添足地列印類似:“ 請您輸...”的多余內容.
所有代碼放在同-一個源檔案中,除錯通過后,拷貝提交該原始碼.
不要使用package陳述句,不要使用jdk1.7及以上版本的特性,
主類的名字必須是: Main, 否則按無效代碼處理.
解題思路
本題在求解的時候,很多小伙伴通常會想到使用暴力法來解決,按照折線段走的順序往下推,這種方法雖然理論上是可行的,并且我最開始也是嘗試使用了這一種方法,但是后來發現對于大量的資料,就比如本題中資料的范圍是10的9次方,對于如此龐大的資料,在運算起來固然是會超時的,所以就必須想辦法進行優化,
我們仔細觀察這個圖形其實就可以發現,它的“右上部分”和“左下部分”是相似對稱的,如果我們給圖形從中間畫一條“\”的斜線進行平均分割,然后單獨觀察每一部分,其實就可以發現,每一層的邊長其實就是一個等引數列,那么我們就可以定義一個頂點作為每一層折線的終點,那么我們可以根據輸入的坐標,推出該坐標擁有幾層正方形,該坐標距離終點相差多少,然后用完整的層數的邊長總和減去相差的邊長,即可得到結果,具體的解釋可以看下圖:
答案原始碼:
package 一八年省賽真題; import java.util.Scanner; public class Year2018_Bt7_2 { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); long x = scanner.nextLong(); long y = scanner.nextLong(); long n = 0; //記錄當前坐標是第幾層 long d = 0; //記錄當前坐標到這一圈完成還差多長 //如果是上半部分的橫線 if (Math.abs(x)<=y && y>0) { n = y; d = y-x + 2*y; }else if (Math.abs(y)<= x && x>0) { //如果是上半部分的豎線 n = x; d = x+y; }else if (y<0 && Math.abs(x)<=(-y+1) && x<(-y)) { //如果是下半部分的橫線 n = -y; d = -(-y-x); }else if (x<0 && Math.abs(y)<=(-x)) { //如果是下半部分的豎線 n = -x-1; //注意這里需要減1,得到完整的層數 d = -((-x-1) - 2*x -1 + y); } long ans = sum(n) - d; System.out.println(ans); } //計算前n層長度和 private static long sum(long n) { long c = 6*n + 4*n*(n-1); return c; } }
輸出樣例:
其中有不足或者改進的地方,還希望小伙伴留言提出,一起學習!
感興趣的小伙伴可以關注專欄!
灰小猿陪你一起進步!

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/275782.html
標籤:java



