2012年4月12日木曜日

TopCoder SRM147 Div2 600Pts

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

numMales人の男性と、numFemales人の女性が輪をなしている。ある地点から時計回りにカウントし、K番目の人を輪から取り除く(最初の人は1番目、時計回りに次の人を2人目と数える)。取り除いたのちに、次の人を1番目の人として輪から取り除く人を決める。これをnumFemales回繰り返すと、輪から女性がいなくなる。そのようなときに、女性を取り除く前はどのような状態であったかを表す文字列を返すメソッドを作成せよ。先頭は1番最初にカウントされた人の性別に対応し、文字列の並びはそこから時計回りに並んだ人の性別の順になる。例えば、5人の男性と3人の女性がいて、2人ごとに取り除くとした場合、返される文字列は"MFMFMFMM"となる。

私の解答はこちら。

public class PeopleCircle {

 public String order(int numMales, int numFemales, int K) {
  int numPeople = numMales+numFemales;
  char[] gender = new char[numPeople]; // 並びを表す配列
  int pos = 0; // 配列の中で注目している位置
  // 抜けた位置(つまり女性の位置)にtrueが入る配列
  boolean[] isRemoved = new boolean[numPeople];
  for( int i=0 ; i<numFemales ; i++ ){ // 女性の位置を探索
   int n = 0; // 途中の抜けを考慮してカウントした人数
   while( true ){
    if( isRemoved[pos] == false ){ // 抜けていなければカウント
     n++;
    }
    if( n >= K ){ // K人カウントしたところでFの位置が決まる
     break;
    }
    pos = pos >= numPeople-1 ? 0 : pos+1; // 配列の終端に来たら先頭へ
   }
   gender[pos] = 'F';
   isRemoved[pos] = true;
  }
  for( int i=0 ; i<numPeople ; i++ ){ // 上のループでFと確定できない要素はMになる
   gender[i] = gender[i] == 'F' ? 'F' : 'M';
  }
  return String.valueOf(gender);
 }

}

数か月放置したのち、約25分で回答。得点は180.00/600。当時の提出者正解率は50%。案外考えれば解けますね。

0 件のコメント:

コメントを投稿

フォロワー

ブログ アーカイブ

ページビューの合計