2011年12月22日木曜日

TopCoder SRM289 Div2 300Pts

このTopCoderの問題はこちらで見ることができる(要TopCoder登録 & 問題文は英語)。問題文について、おおまかに説明する。

ある物体がxy-座標系の(x,y)(ただしx>0かつy>0)という座標にある。物体はまっすぐx軸方向に1秒当たり1の速さで落ちていく。それ以外にも、物体は障害物に当たる可能性がある。各障害物はx軸方向に水平な線領域である(つまりy軸方向の厚さは0と考える)。物体が障害物に当たる度に、地面への落下は5秒遅れる。この遅れの間に物体は障害物の右端へ向かい、その位置から垂直に再び落ちる。

初期状態の位置を表す(x,y)と、障害物の位置を表す文字列型の配列obstacles[]が与えられたとき、最終的にx軸に届くまでに何秒かかったかを返すメソッドを作成せよ。obstacles[]の各要素は"y x1 x2"という形式で与えられ、yは障害物のy座標の値、x1とx2はそれぞれ障害物の左端と右端を表している。なお、y、x1、x2は3桁の整数で、桁数が2桁以下であれば先頭に0が埋められている。また、障害物のy座標に重複はないものとする。

私の解答はこちら。

import java.util.Arrays;

public class ObjectFall {

 public int howLong(int x, int y, String[] obstacles) {
  Arrays.sort(obstacles);
  // かかった時間。yの値で初期化すれば、物体に当たった回数のみ考えればよい。
  int nTime = y; 
  int cy = y; // cx、cyは現在の物体の位置を表す。
  int cx = x;
  // y座標の大きい方から検討
  for( int i=obstacles.length-1 ; i>=0 ; i-- ){
   String[] coords = obstacles[i].split(" ");
   int yPos = Integer.parseInt(coords[0]); // 先頭に0があってもこれでOK
   int xl = Integer.parseInt(coords[1]);
   int xr = Integer.parseInt(coords[2]);
   // 衝突の条件はx座標が間に収まることと、y座標が現在の位置以下にあること。
   if( cy >= yPos && cx >= xl && cx <= xr ){
    nTime += 5;
    cy = yPos;
    cx = xr;
   }
  }
  return nTime;
 }

}

得点は184.29/250、中央値よりは下の点数。最初にy座標でソートして、y座標の値が大きい障害物から順番に検討していけばよいということに気付いたものの、ソート(Arrays.sort(obstabcles))の実現方法の思いつきに時間がかかってしまいました。

0 件のコメント:

コメントを投稿

フォロワー

ブログ アーカイブ

ページビューの合計