google code jam 2011 Qualification Round B Magicka

方針

  • 素直にシミュレーション

回答

#include <iostream>
#include <vector>
#include <string>
#include <cmath>
#include <cstdlib>
#include <map>
#include <algorithm>



using namespace std;

string make_key(char a, char b){
  string ret(1, a);
  ret += b;
  return ret;
}

class magicka{
public:
  map<string, char> combine;
  map<string, char> opposed;
  vector<char> elem_list;

  void register_comb(string s){
    combine[make_key(s[0], s[1])] = s[2];
    combine[make_key(s[1], s[0])] = s[2];
  }

  void register_opposed(string s){
    opposed[make_key(s[0], s[1])] = 0;
    opposed[make_key(s[1], s[0])] = 0;
  }

  void receive_element(char x){
    if(elem_list.size() > 0){
      map<string, char>::iterator it = combine.find(make_key(elem_list.back(), x));
      if(it != combine.end()){
	elem_list.back() = it->second;
      }
      else{
	bool clear_flag = false;
	for(size_t i = 0; i < elem_list.size(); ++i){
	  if(opposed.find(make_key(elem_list[i], x)) != opposed.end()){
	    clear_flag = true;
	    elem_list.clear();
	    break;
	  }
	}
	if(!clear_flag){	  
	  elem_list.push_back(x);
	}
      }
    }
    else{
      elem_list.push_back(x);
    }
  }

  ostream& print_list(ostream& os) const {
    os << "[";
    if(elem_list.size() > 0){
      for(size_t i = 0; i < elem_list.size() - 1; ++i){
	os << elem_list[i] << ", ";
      }
      os << elem_list.back();
    }
    return os << "]";
  }

  void print_all(){
    cout << "combine" << endl;
    for(map<string, char>::iterator it = combine.begin(); it != combine.end(); ++it){
      cout << it->first << "\t" << it->second << endl;
    }
    cout << "opposed" << endl;
    for(map<string, char>::iterator it = opposed.begin(); it != opposed.end(); ++it){
      cout << it->first << "\t" << it->second << endl;
    }
    cout << "elem_list" << endl;
    print_list(cout) << endl;
  }
};

ostream& operator<<(ostream& os, const magicka& m){
  return m.print_list(os);
}

void solve(int x){
  magicka mag;
  int c, d, n;
  string buf;
  cin >> c;
  for(int i = 0; i < c; i++){
    cin >> buf;
    mag.register_comb(buf);
  }
  cin >> d;
  for(int i = 0; i < d; ++i){
    cin >> buf;
    mag.register_opposed(buf);
  }
  cin >> n >> buf;
  for(int i = 0; i < n; ++i){
    mag.receive_element(buf[i]);
    //mag.print_all();
  }
  cout << "Case #" << x << ": " << mag << endl;
}

int main(int argc, char *argv[]){
  int n;
  cin >> n;

  for(int i = 0; i < n; ++i){
    solve(i + 1);
  }

  return 0;
}