前提・実現したいこと
ロジック力強化のためにアルゴリズムの勉強をしているのですが、
以下の問題のアルゴリズムをどうすればよいかわかりません。
問題文
あなたは現在 xy 平面上の格子点 (X1,Y1) にいます。 あなたは、格子点 (X2,Y2) に到達したいです。 あなたは、以下のような移動を行うことができます。 ・今いる点の x 座標が偶数のとき、 y 軸の正の方向に移動する。 ・今いる点の x 座標が奇数のとき、 y 軸の負の方向に移動する。 ・今いる点の y 座標が偶数のとき、 x 軸の正の方向に移動する。 ・今いる点の y 座標が奇数のとき、 x 軸の負の方向に移動する。 これらの移動を繰り返すことで格子点 (X2,Y2) に到達するために必要な総移動距離の最小値を求めてください。
自分の書いたソースコード
以下、現状のソースコードになります。
到達目標座標の偶奇が考慮できていないため、無限ループに入ってしまいます。
Java
1import java.util.*; 2 3public class Main { 4 5 /* 移動距離カウント用 */ 6 static int c = 0; 7 8 public static void main(String[] args) { 9 Scanner sc = new Scanner(System.in); 10 11 /* 今いる座標 */ 12 int x = sc.nextInt(); 13 int y = sc.nextInt(); 14 15 /* 到達目標座標 */ 16 final int x2 = sc.nextInt(); 17 final int y2 = sc.nextInt(); 18 19 int xyc; 20 int yxc; 21 22 int x1 = x; 23 int y1 = y; 24 25 /* y→xの順 */ 26 while (true) { 27 if (x1 % 2 == 0) { /* 今いるx座標が偶数 */ 28 y1 += moveCoordinate(y1, y2, "even"); 29 } else if (Math.abs(x1 % 2) == 1) { /* 今いるx座標が奇数 */ 30 y1 += moveCoordinate(y1, y2, "odd"); 31 } 32 33 System.out.println(x1 + " " + y1); 34 35 if (x1 == x2 && y1 == y2) { 36 break; 37 } 38 39 if (y1 % 2 == 0) { /* 今いるy座標が偶数 */ 40 x1 += moveCoordinate(x1, x2, "even"); 41 } else if (Math.abs(y1 % 2) == 1) { /* 今いるy座標が奇数 */ 42 x1 += moveCoordinate(x1, x2, "odd"); 43 } 44 45 System.out.println(x1 + " " + y1); 46 47 if (x1 == x2 && y1 == y2) { 48 break; 49 } 50 } 51 //System.out.println(c); 52 yxc = c; 53 54 c = 0; 55 x1 = x; 56 y1 = y; 57 58 System.out.println(); 59 /* x→yの順 */ 60 while (true) { 61 if (y1 % 2 == 0) { /* 今いるy座標が偶数 */ 62 x1 += moveCoordinate(x1, x2, "even"); 63 } else if (Math.abs(y1 % 2) == 1) { /* 今いるy座標が奇数 */ 64 x1 += moveCoordinate(x1, x2, "odd"); 65 } 66 67 System.out.println(x1 + " " + y1); 68 69 if (x1 == x2 && y1 == y2) { 70 break; 71 } 72 73 if (x1 % 2 == 0) { /* 今いるx座標が偶数 */ 74 y1 += moveCoordinate(y1, y2, "even"); 75 } else if (Math.abs(x1 % 2) == 1) { /* 今いるx座標が奇数 */ 76 y1 += moveCoordinate(y1, y2, "odd"); 77 } 78 79 System.out.println(x1 + " " + y1); 80 81 if (x1 == x2 && y1 == y2) { 82 break; 83 } 84 } 85 //System.out.println(c); 86 xyc = c; 87 88 if (xyc < yxc) { /* x軸→y軸の順 */ 89 System.out.println(xyc); 90 } else { /* y軸→x軸の順 */ 91 System.out.println(yxc); 92 } 93 94 } 95 96 public static int moveCoordinate(int a, int b, String evenness) { 97 if (evenness == "even") { // 正方向へ移動 98 if (a < b) { 99 c += Math.abs(b - a); 100 return Math.abs(b - a); 101 } else /* if (a >= b) */{ 102 c++; 103 return 1; 104 105 } 106 107 } else if (evenness == "odd") { // 負方向へ移動 108 if (a > b) { 109 c += Math.abs(a - b); 110 return -(Math.abs(a - b)); 111 } else /* if (a <= b) */{ 112 c++; 113 return -1; 114 } 115 } 116 return 0; 117 } 118} 119
補足情報
入力は以下の形式で標準入力から与えられる。
X1 Y1 X2 Y2
入力例1
0 1 5 1
出力例1
7
(0,1) → (0,2) → (5,2) → (5,1) と移動すると総移動距離は 7 となり、これは最小です。
入力例2
100000000 100000000 -100000000 -100000000
出力例2
400000004
(100000000,100000000) → (100000001,100000000) → (100000001,−100000001) → (−100000000,−100000001) → (−100000000,−100000000) と移動すると総移動距離は 400000004 となり、これは最小です。
入力例3
3 -1 4 8
出力例3
12