2012年4月14日土曜日

TopCoder SRM148 Div2 600Pts

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

キーボードのキー配列が入れ替えられ、ユーザは何をタイプしたか覚えようとしている。typedというスクリーン上に表示された文字列と、switches[]というキー配列の交換の様子が与えられたdecipherというメソッドを作成せよ。このメソッドは本来意図していたメッセージを返すものである。また、キー配列の交換は1度以上起きるものとする。例えば、もし誰かがAとSを交換し、SとDを交換したとすれば、Aがもともとあった場所にはDが、Dがもともとあった場所にはSが、Sがもともとあった場所にはAがあることになる。交換を表すswithches[]の各要素は"*:*という形式で表される。例えば先述の交換は{"A:S","S:D","D:A"}ということになる。なお、各要素の文字は順番が逆でも同じ結果になることに注意。

私の解答はこちら。

public class CeyKaps {

 public String decipher(String typed, String[] switches) {
  char[] keys = new char[26]; // 26文字のキーボードを表す配列と思っておく
  for( int i=0 ; i<keys.length ; i++ ){ // 値の初期設定
   keys[i] = (char)('A' + i);
  }
  // キーボードのボタンを交換していく
  for( int i=0 ; i<switches.length ; i++ ){
   char c1 = switches[i].charAt(0);
   char c2 = switches[i].charAt(2);
   int pos1 = searchFromKeys(keys, c1);
   int pos2 = searchFromKeys(keys, c2);
   swap(keys, pos1, pos2);
  }
  // typedの内容が実際に何になるかはkeysでわかる
  StringBuilder sb = new StringBuilder();
  for( int i=0 ; i<typed.length() ; i++ ){
   int pos = typed.charAt(i) - 'A';
   sb.append(keys[pos]);
  }
  return sb.toString();
 }
 // targetという文字のある位置を見つける。存在しないなら-1。
 private int searchFromKeys(char[] keys, char target){
  for( int i=0 ; i<keys.length ; i++ ){
   if( target == keys[i] ) return i;
  }
  return -1;
 }
 // keysのp1とp2の要素を入れ替える
 private void swap(char[] keys, int p1, int p2){
  char tmp = keys[p1];
  keys[p1] = keys[p2];
  keys[p2] = tmp;
 }
}

得点は449.94/600、1回のsubmitでシステムテストクリア。提出者の正解率は約89%。テストのコードの良さで正解率が決まってしまっているような気がします。

0 件のコメント:

コメントを投稿

フォロワー

ブログ アーカイブ

ページビューの合計