Problem:
あみだくじ II

縦線が n 本のあみだくじがあります。このあみだくじは以下の条件を満たしています。

横線は真横に引きます。斜めに引くことはありません。

横線は必ず隣り合った縦線同士をつなぎます。つまり、横線が縦線をまたぐことはありません。

どの縦線についても同じ点から左右同時に横線が出ることはありません。つまり、横線が縦線を横切ることはありません。

当りはひとつだけです。

下図 に n = 5 のときの、あみだくじの例を示します。上側の数字は縦線の番号(左から1, 2, 3, 4, 5 ) を表します。☆が当たりです。

縦線の本数 n、選んだ縦線の番号 m、あみだくじの当りの場所、各段における横線の有無を読み込んで、当りにたどり着けるかどうかの判定を出力するプログラムを作成してください。ただし、与えられたあみだくじの任意の位置に1 本だけ横線を付け加えることができるものとします（付け加えなくてもかまいません）。横線を1 本付け加えた後のあみだくじも前述の条件を満たしていなければなりません。

Input

複数のデータセットが与えられます。各データセットは以下のとおりです：

１行目に、縦線の本数 n (1 < n ≤ 10) が書かれています。

２行目には、選んだ縦線の番号 m (1 ≤ m ≤ n) が書かれています。

３行目には、当りの場所（図でいう☆）が左から数えて何番目かが書かれています。

４行目には、あみだくじの段数 d (1 ≤ d ≤ 30) が書かれています。

５行目以降は、図に対応する数字の並びのように、あみだくじの上から順に、各縦線の間に横線があるときを 1、ないときを 0 として、n - 1 つの数字が並んでいます。

入力は１つの 0 が書かれた行で終わります。

Output

各データセットについて、選んだ縦線の番号 m から当りにたどり着けるかどうかに応じて以下の値を出力してください。

横線を引かなくても当りにたどり着けるときは 0 を出力してください。

横線を1 本引けば当りにたどり着けるときは、その中で最も出発側（図でみて上）に近い横線の位置を出力してください。出発側から数えて何段目（図 を参考にしてください）に、左から数えて何番目の縦線から右に向かって横線を引くかを半角の空白で区切って出力してください。

横線を1 本引いても当りにたどり着けないときには 1 を出力してください。

Sample Input

5
2
3
9
1010
1001
0100
1001
0010
1000
0100
0101
1010
0

Output for the Sample Input

6 4

Solution in JAVA (judge verdict: Wrong Answer)

import java.util.Scanner;

public class Main {

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n, m, g, d;
		int[][] horizontalLine = null;
		while((n = sc.nextInt()) != 0){
			m = sc.nextInt();
			g = sc.nextInt();
			d = sc.nextInt();
			horizontalLine = new int[d][n - 1];
			for(int i = 0; i < horizontalLine.length; i++){
				String input = sc.next();
				for(int j = 0; j < horizontalLine[0].length; j++){
					horizontalLine[i][j] = Integer.parseInt(String.valueOf(input.charAt(0 + j)));
				}
			}
			if(m - 1 == getLineToGoal(g - 1, horizontalLine)[0]){
				System.out.println("0");
			}else{
				int[] o = getNewLinePosition(getPosition(m - 1, horizontalLine), getLineToGoal(g - 1, horizontalLine), horizontalLine);
				System.out.println((o == null)? "1" : ((o[0] + 1) + " " + (o[1] + 1)));
			}
		}
		sc.close();
	}
	
	public static int[] getNewLinePosition(int[] pos, int[] goal, int[][] horizontalLine){
		//経路情報を上から参照していく
		for(int d = 0; d < pos.length; d++){
			//隣り合っていて、線を引くことが出来る場合段数を返す
			if(Math.abs(pos[d] - goal[d]) == 1){
				int n = Math.min(pos[d], goal[d]);
				//左チェック
				if(n == 0 || horizontalLine[d][n -1] == 1)	continue;
				//右チェック
				if(n == horizontalLine[0].length || horizontalLine[d][n] == 1)	continue;
				return new int[]{d, Math.min(pos[d], goal[d])};
			}
		}
		return null;
	}
	public static int[] getPosition(int n, int[][] horizontalLine){
		int[] pos = new int[horizontalLine.length];
		//横線情報を上から参照していく
		int currentPos = n;
		int tmp;
		for(int d = 0; d < horizontalLine.length; d++){
			tmp = currentPos;
			//左となりの縦線チェック
			if(tmp != 0 && horizontalLine[d][tmp - 1] == 1){
				currentPos--;
			}
			//右となりの縦線チェック
			else if(tmp != horizontalLine[0].length && horizontalLine[d][tmp] == 1){
				currentPos++;
			}
			pos[d] = currentPos;
		}
		return pos;
	}

	public static int[] getLineToGoal(int goal, int[][] horizontalLine){
		int[] goalOn = new int[horizontalLine.length];
		//横線情報を下から参照していく
		int currentGoal = goal;
		for(int d = horizontalLine.length - 1; d >= 0; d--){
			//左となりの縦線チェック
			if(currentGoal != 0 && horizontalLine[d][currentGoal - 1] == 1){
				currentGoal--;
			}
			//右となりの縦線チェック
			if(currentGoal != horizontalLine[0].length && horizontalLine[d][currentGoal] == 1){
				currentGoal++;
			}
			goalOn[d] = currentGoal;
		}
		return goalOn;
	}
}