このTopCoderの問題はこちらで見ることができる(要TopCoder登録 & 問題文は英語)。問題文について説明する。
あなたはareaMap[]という文字列型配列によって形状を示された山にいる。i番目の要素のj番目の文字は0-9の数字であり、それは(i, j)における標高を表している。あなたは以下のルールに従ってこの山を歩く。
- (0, 0)から動き始める。
- (i, j)にいるときは(i+1, j), (i, j-1), (i-1, j), (i, j+1)の順に高さを確かめる。そしてまだ入ったことがなく、かつ現在の標高と確かめている位置の標高がheightDifference以下であれば、その方向へ進む。
- 上記4方向のどこにも動けなくなった時点で歩くのを止める。
私の解答はこちら。
public class MountainWalk { public int cellsVisited(String[] areaMap, int heightDifference) { int h = areaMap.length; int w = areaMap[0].length(); boolean[][] isVisited = new boolean[h][w]; // 訪問済ならtrue、未訪問ならfalse int hPos = 0; // 現在のx方向の位置 int wPos = 0; // 現在のy方向の位置 int nStep = 1; // 歩いた座標の総数 isVisited[0][0] = true; while( true ){ int[] i = {hPos + 1, hPos, hPos - 1, hPos}; // 探索順序 int[] j = {wPos, wPos - 1, wPos, wPos + 1}; int idx = -1; // 訪問できる箇所を表す添字、-1なら訪問できる箇所はないと考える for( int k = 0 ; k<i.length; k++ ){ // フィールドの外にはみ出ず、まだ未訪問の位置で、 if( isInField(i[k], 0, h) && isInField(j[k], 0, w) && isVisited[i[k]][j[k]] == false ){ int from = areaMap[hPos].charAt(wPos) - '0'; int to = areaMap[i[k]].charAt(j[k]) - '0'; if( Math.abs((from - to)) <= heightDifference ){ // 高さが侵入可能な差しかないなら idx = k; hPos = i[k]; // その方向へ進む wPos = j[k]; nStep++; // 歩いた座標の数を増やす isVisited[i[k]][j[k]] = true; // 訪問済みフラグを立てる break; } } } if( idx == -1 ) break; } return nStep; } private boolean isInField(int i, int from, int to){ // 移動先がフィールド内部か判定 if( i >= from && i < to ){ return true; }else{ return false; } } }
得点は162.89/250、1回のsubmitでシステムテストクリア。中央値は約148点。250点の問題にしては実装量が多いですね。
0 件のコメント:
コメントを投稿