Java初心者の競技プログラミング日記

Dvorak配列でjavaを書いてます

No.240 ナイト散歩

方針

・問題文にある8座標にそれぞれ分岐していくような再帰関数を書く

import static java.lang.System.*;
import java.util.*;

public class Main {
	static Scanner sc = new Scanner(System.in);
	static int gx = sc.nextInt();
	static int gy = sc.nextInt();
	public static void main(String[] args) {
		out.println(dfs(0,0,0)?"YES":"NO");
	}
	static boolean dfs(int x, int y, int n) {
		if (n>3) return false;
		if (x==gx && y==gy) return true;
		return (
				dfs(x-2,y-1,n+1) ||
				dfs(x-2,y+1,n+1) ||
				dfs(x-1,y-2,n+1) ||
				dfs(x-1,y+2,n+1) ||
				dfs(x+1,y-2,n+1) ||
				dfs(x+1,y+2,n+1) ||
				dfs(x+2,y-1,n+1) ||
				dfs(x+2,y+1,n+1)
		);
	}
}


ごく普通の再帰関数(深さ優先探索)ですが、戻り値の部分が少し変わっています。

・return (条件式1 || 条件式2 || 条件式3……)
・return (関数1 || 関数2 || 関数3……)

と書いた場合、これはif文にある条件式の形になるので、
これらの条件式(あるいは関数の戻り値)のうち一つでもtrueならばtrueを戻すことになります。

今回の問題では、n>3になるか目標地点に到達するまで再帰関数を伸ばし続け、前者の終了条件ではfalse、後者ではtrueが返ります。すると、3番目のreturnの中身は最終的に

・return (false || false || false || true || false || false || false......)

となります。したがって、一度でも目標地点に到達していればtrue、一度も目標地点に到達できなかったならfalseが返ることになり、戻り値の書き方が少し特殊だったこの再帰関数も、正しく動作していることになります。