この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 件のコメント:
コメントを投稿