螺旋折線(藍橋杯)


如圖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  

【輸出格式】
輸出dis(X, Y)  


【輸入樣例】
  0 1

【輸出樣例】
  3


資源約定:
峯值內存消耗(含虛擬機) < 256M
CPU消耗  < 1000ms


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

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

我的思路:我感覺我的思路是對的,但由於超時的原因只能測試50%的數據,剩下的50%數據超時。這個題是有規律的,首先

從(0,0)點到(1,-1)點可以算是一個週期,(1,-1)就是一個邊界點,而且第一週期四條邊的值分別爲1,1,2,2,第二週期的值爲3,3,4,4,每增加一個週期,四條邊的長度都分別+2,利用這個規律可以將算法分爲兩部分:一種是判斷輸入的點是在第一週期的點的情況;第二種是判斷輸入的點在第一週期之後的的情況。如果輸入的點在第一週期之後,則從邊界點依次向左、向上、向右、向下移動,直到找到輸入的點爲止輸出變長即可。

代碼如下:

import java.math.BigInteger;
import java.util.Scanner;

public class 螺旋折線2
{
	private static long n;    //輸入的橫座標
	private static long m;    //輸入的縱座標
	private static long s;    //到邊界點時的邊長
	private static long x;    //邊界點的橫座標
	private static long y;    //邊界點的縱座標
	
	public static boolean check()   //判斷是否到了輸入的點
	{
		if(x==n&&y==m)
		{
			return true;
		}
		return false;
	}
	
	public static void result()   //到輸入點的位置時輸出變長
	{
		boolean flag = check();
		if(flag)
		{
			System.out.println(s);
			System.exit(0);
		}
	}
	
	public static void main(String[] args)
	{
		Scanner in = new Scanner(System.in);
		n = in.nextLong();
		m = in.nextLong();
		x = 1L;   //邊界點橫座標
		y = -1L;  //邊界點的縱座標
		s = 6L;   //到邊界點時的邊長
		long a=1L,b=1L,c=2L,d=2L;  //第一層邊的值,以後每層對應邊數加2
		if(n==0&&m==0) {System.out.println(0);System.exit(0);}
		if(n==-1&&m==0) {System.out.println(1);System.exit(0);}
		if(n==-1&&m==1) {System.out.println(2);System.exit(0);}
		if(n==0&&m==1) {System.out.println(3);System.exit(0);}
		if(n==1&&m==1) {System.out.println(4);System.exit(0);}
		if(n==1&&m==0) {System.out.println(5);System.exit(0);}
		while(true)  //邊界點之後的點
		{
			result();   //檢測是否到了輸入的點
			a = a + 2;
			for(long i=1L;i<=a;++i)   //每一層都是先往左移動
			{
				x = x - 1;    //橫座標-1
				s = s + 1;    //邊數+1
				result();   //檢測是否到了輸入的點
			}
			b = b + 2;
			for(long i=1L;i<=b;++i)
			{
				y = y + 1;    //縱座標+1
				s = s + 1;    //邊數+1
				result();     //檢測是否到了輸入的點
			}
			c = c + 2;
			for(long i=1L;i<=c;++i)
			{
				x = x + 1;   //橫座標+1
				s = s + 1;   //邊數+1
				result();    //檢測是否到了輸入的點
			}
			d = d + 2;
			for(long i=1L;i<=d;++i)
			{
				y = y - 1;   //縱座標-1
				s = s + 1;   //邊數+1
				result();    //檢測是否到了輸入的點
			}
		}
	}
}

運行結果:

輸入:

2000 2000

輸出:

16000000

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章