2012年1月4日水曜日

TopCoder SRM298 Div2 250Pts

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

進捗インジケータの動きを制御するプログラムをシミュレーションする。インジケータは4つの状態(文字)を取る、1つの文字列からなる。文字は|、-、\、/からなる。プログラムでは文字列の出力命令は<instr%gt; <secs>という形式で与えられる。instrは4つの取り得る動き、secsはその動きの継続時間を表している。動きは1秒間に1つである。4つの取り得る動きとは次のことを指す。

  • L:左にスピンする。|は\、\は-、-は/、/は|に状態が変化する。
  • R:右にスピンする。\は|、|は/、/は-、-は\に状態が変化する。
  • S:そのままで状態は変化しない。
  • F:バーは90度回転する。\は/、/は\、-は|、|は-になる。

つまり、"F03L02"という文字列と初期状態-が与えらえると、"-|-|\-"という文字列が返されることになる。

startStateという初期状態とprogramというプログラムが与えられたときに、その結果生成される文字列を返せ。文字列のi番目の文字はi秒後の状態を表すことになる。すなわち0秒(開始時点)は、初期状態(startState)に一致する。programは3*k(kは整数)の文字数からなる。3文字ごとに見ると、instrが1文字、secsが2文字になっている。secsは2桁になるよう0埋めされることがある。startStateは4つの状態のいずれかである。

私の解答はこちら。

public class IndicatorMotion {

 public String getMotion(String program, char startState) {
  StringBuffer sb = new StringBuffer();
  String indicator = "|\\-/";
  int pos = 0;
  for( int i=0 ; i<indicator.length() ; i++ ){
   if( startState == indicator.charAt(i) ){
    pos = i;
    break;
   }
  }
  sb.append(startState);
  for( int i=0 ; i<program.length()/3 ; i++ ){
   String dir = program.substring(i*3, (i+1)*3);
   char instr = dir.charAt(0);
   int secs = Integer.parseInt(dir.substring(1));
   int nMove = add(instr);
   for( int j=0 ; j<secs ; j++ ){
    pos = (pos+nMove)%(indicator.length()); // (1)
    sb.append(indicator.charAt(pos));
   }
  }
  return sb.toString();
 }
 private int add(char c){
  if( c == 'L' ){
   return 1;
  }else if( c == 'R' ){ 
   return 3; // -1としたら上の(1)はpos+nMove+indicator.lengthになる
  }else if( c == 'S' ){
   return 0;
  }else{
   return 2;
  }
 }
}

得点は163.50/250、中央値は約123点。4つのinstrの位置関係を表すのがポイントかと思います。コードだけでなく、ときには紙も利用するのが良いのでしょう。

0 件のコメント:

コメントを投稿

フォロワー

ブログ アーカイブ

ページビューの合計