2012年9月3日月曜日

TopCoder SRM420 Div2 500Pts

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

あなたは大みそかをとても楽しみにしている。次の大みそかはそんなに遠くなく、あなたはそれを楽しみにしている。そして、ある日、ある疑問で目が覚めることになる。「待てよ、大みそかはどのぐらい離れているんだ?」

この質問に答えるため、今年がどの程度終わったかを示すプログレスバーという、簡単なアプリケーションを作成することにした。この問題においては、目標はこのアプリケーションのもっとも重要なパートを実装することである。つまり、現在時刻を示すcurrentDateという文字列を受け取ったときに、百分率でその年の進捗状況を返すというものである。currentDateという変数は"Month DD, YYYY HH:MM"という文字列で与えられる。ここで、Monthは月の名前を表し、YYYYは西暦、DD、HH、MMは日、時間、分を二桁の数値で表したものである。なお、0埋めされる可能性がある(訳注:例えば5月の場合MMは05ということになる)。

私の実装はこちら。

public class YearProgressbar {

 public double percentage(String currentDate) {
  int[] days = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
  // 現在時刻の解釈
  String[] date = currentDate.split(" ");
  int year = Integer.parseInt(date[2]);
  int month = monthInt(date[0]);
  int day = Integer.parseInt(date[1].substring(0, 2));
  int hour = Integer.parseInt(date[3].substring(0, 2));
  int minutes = Integer.parseInt(date[3].substring(3));
  boolean leap = isLeap(year); // 今年はうるう年か?
  int daysInYear = leap ? 366 : 365;
  int secondsInYear = daysInYear * 24 * 3600; // 1年間の秒数

  int alreadyPassedDays = 0;
  for( int i=0 ; ilt;month ; i++ ){
   alreadyPassedDays += days[i];
   if( leap && i == 1 ) alreadyPassedDays++; // 経過した日数を計算
  }
  int alreadyPassedSeconds = minutes * 60 + hour * 3600 +
          (day - 1 + alreadyPassedDays) * 24 * 3600 ; // 今年の経過秒数を求めている
  return alreadyPassedSeconds * 1.0 / secondsInYear * 100;
 }

 private boolean isLeap(int year){
  if( year % 400 == 0 || (year % 4 == 0 && year % 100 != 0) ){
   return true;
  }
  return false;
 }

 private int monthInt(String month){ // monthという文字列から月の値を返す。失敗すれば-1。
  String[] monthString = {"January", "February", "March", "April", "May", "June",
            "July", "August", "September", "October", "November", "December"};
  for( int i=0 ; i<monthString.length ; i++ ){
   if( month.equals(monthString[i]) ){
    return i;
   }
  }
  return -1;
 }
}

得点は315.02/500、1回のsubmitでシステムテストクリア。中央値は150点。愚直な実装ではありますが、これで問題なし。分単位までで良かったので、秒単位に変換する必要はありませんでしたね。

0 件のコメント:

コメントを投稿

フォロワー

ブログ アーカイブ

ページビューの合計