ぱーぽーの競プロ記

競技プログラミングに関することを書きます。

AOJ 0198 Trouble in Artist Shinagawa's Artifact

・概要
問題文はこちら
http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=0198

サイコロの6面それぞれに違う色が塗られます。
その中で同じ色の組み合わせのサイコロを見つけ、残り何個サイコロがあればよいかを求める問題です。


・解法
サイコロをころころ回してやれば解くことができます(雑)

この問題で重要になるサイコロの特徴として、
サイコロの状態は全部で24通りあるということです。

だから一つのサイコロをころころ回して24通り試せば、ダブっているサイコロを簡単に見つけることができます。
あとは各サイコロの状態を set などに保管し、最後に24で割れば求めたい値を出力することができます。
サイコロの状態をint型に変換する関数を作っておく必要があります。


ソースコード

#include<iostream>
#include<string>
#include<set>
#include<map>
#include<vector>
using namespace std;

map<string, int> colors;

struct Dice{
  //top, front, right, left, back, bottom;
  int side[6];
  Dice(){}
   
  int convert(){
    int val = 0;
    for(int i = 0 ; i < 6 ; i++){
      val = 10*val + side[i];
    }
    return val;
  }

  void rotate(int op){
    int tmp = ' ';
    //右に倒す
    if(op==0){
      tmp = side[0];
      side[0] = side[3];
      side[3] = side[5];
      side[5] = side[2];
      side[2] = tmp;
    }

    //前に倒す
    if(op==1){
      tmp = side[0];
      side[0] = side[4];
      side[4] = side[5];
      side[5] = side[1];
      side[1] = tmp;
    }
      
    //左に倒す
    if(op==2){
      tmp = side[0];
      side[0] = side[2];
      side[2] = side[5];
      side[5] = side[3];
      side[3] = tmp;
    }
      
    //後ろに倒す
    if(op==3){
      tmp = side[0];
      side[0] = side[1];
      side[1] = side[5];
      side[5] = side[4];
      side[4] = tmp;
    }

    //topとbottomを軸に右回転
    if(op==4){
      tmp = side[1];
      side[1] = side[2];
      side[2] = side[4];
      side[4] = side[3];
      side[3] = tmp;
    }
      
    //topとbottomを軸に左回転
    if(op==5){
      tmp = side[1];
      side[1] = side[3];
      side[3] = side[4];
      side[4] = side[2];
      side[2] = tmp;
    }
  }
};

int n;
set<int> pattern;
Dice dice[30];

void init(){
  colors["Red"] = 1;
  colors["Yellow"] = 2;
  colors["Blue"] = 3;
  colors["Magenta"] = 4;
  colors["Green"] = 5;
  colors["Cyan"] = 6;
}

void solve(){
  for(int i = 0 ; i < n ; i++){
    for(int j = 0 ; j < 6 ; j++){
      if(j < 4)dice[i].rotate(0);
      else if(j==4)dice[i].rotate(3);
      else{
        dice[i].rotate(1);
        dice[i].rotate(1);
      }
      for(int k = 0 ; k < 4 ; k++){
        dice[i].rotate(4);
        pattern.insert(dice[i].convert());
      }
    }
  }
}

int main(){
  init();
  while(cin >> n, n){
    pattern.clear();
    for(int i = 0 ; i < n ; i++){
      for(int j = 0 ; j < 6 ; j++){
        string s;
        cin >> s;
        dice[i].side[j] = colors[s];
      }
    }
    solve();
    cout << n - pattern.size()/24 << endl;
  }
  return 0;
}