2012年12月13日木曜日

AOJをといたの続き

AOJ 0501
文字変換表を渡されて、対応する文字だけ置き換える。
mapにもって該当すれば置き換えるだけ。

#include<iostream>
#include<map>
using namespace std;
 
int main(void){
    int n,m;
    while(cin >> n, n != 0){
        char c, d;
        map<char, char> tb;
        for(int i = 0; i < n; i++){
            cin >> c >> d;
            tb[c] = d;
        }
        cin >> m;
        for(int i = 0; i < m; i++){
            cin >> c;
            if(tb.find(c) != tb.end())
                cout << tb[c];
            else
                cout << c;
        }
        cout << endl;
    }
    return 0;
}
出力は改行するもんだと思ってた。騙された!

AOJ 0502
サイコロを指示通り転がして上面になった目の合計。
#include<iostream>
#include<string>
using namespace std;
 
int main(void){
  int a6,
      a5,
  a4, a1, a3,
      a2;
  string str;
  int n, temp;
  while(cin >> n, n != 0){
    a1 = 1;
    a2 = 2;
    a3 = 3;
    a4 = 4;
    a5 = 5;
    a6 = 6;
    int ans = 1;
    for(int i = 0; i < n; i++){
      cin >> str;
      if(str == "North"){
    temp = a1;
    a1 = a2;
    a2 = a6;
    a6 = a5;
    a5 = temp;
      }
      if(str == "East"){
    temp = a1;
    a1 = a4;
    a4 = a6;
    a6 = a3;
    a3 = temp;
      }
      if(str == "West"){
    temp = a1;
    a1 = a3;
    a3 = a6;
    a6 = a4;
    a4 = temp;
      }
      if(str == "South"){
    temp = a1;
    a1 = a5;
    a5 = a6;
    a6 = a2;
    a2 = temp;
      }
      if(str == "Right"){
    temp = a2;
    a2 = a3;
    a3 = a5;
    a5 = a4;
    a4 = temp;
      }
      if(str == "Left"){
    temp = a2;
    a2 = a4;
    a4 = a5;
    a5 = a3;
    a3 = temp;
      }
      ans += a1;
    }
    cout << ans << endl;
  }
  return 0;
}
全部の指示を丁寧に実装しました。a1~6をサイコロ形に書いてるのがまたひどい。
単にスパゲティーなだけやん?

AOJ 0503
隣にしか動かせないハノイの塔
#include
#include
using namespace std;
int solve(int, int, int);
 
int main(void){
  int n,m,l;
 
  while(cin >> n >> m, n != 0 && m != 0){
    int ans = 0;
    int a[3] = {0}, temp;
 
    for(int i = 0; i < 3; i++){
      cin >> l;
      for(int j = 0; j < l; j++){
    cin >> temp;
    a[i] |= 1 << temp - 1;
      }
    }
 
    ans = min(solve(a[0], a[1], a[2]), solve(a[2], a[1], a[0]));
 
    if(ans > m)
      cout << -1 << endl;
    else
      cout << ans << endl;
  }
 
  return 0;
}
 
int solve(int a, int b, int c){
  if(a == 0 && b == 0) return 0;
  if(c & 1) return solve(a >> 1, b >> 1, c >> 1);
  if(b & 1) return solve(c >> 1, b >> 1, a >> 1) + 1 + solve((a|b|c) >> 1, 0, 0);
  if(a & 1) return solve(a >> 1, b >> 1, c >> 1) + 2*solve((a|b|c) >> 1, 0, 0) + 2;
}
式を再帰的に~とか一番小さいコップは無視出来るので~とか数学的過ぎてよく分からん。
最初はコップを位置からシミュレーションしようと思ったけどコードがスパゲティ過ぎて挫折。
あきらめてJOIの解説見に行きました。

というわけで2日間でこれだけといたので、後はとりあえずビットDPとかワーシャルフロイドとかunion find木とかだけやっとけば5完とかいけそう。DPもちょっと練習したい。

0 件のコメント:

コメントを投稿