2012年6月8日金曜日

TopCoder SRM394 Div2 250Pts

この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方向のどこにも動けなくなった時点で歩くのを止める。
上記のルールに従ったとき、歩いた座標の総数を返せ。なお、(0, 0)は最初に1ヶ所歩いたものとみなすものとし、2回以上同じ場所を歩くことはないものとする。

私の解答はこちら。

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 件のコメント:

コメントを投稿

フォロワー

ブログ アーカイブ

ページビューの合計