日々精進

aikoと旅行とプログラミング

【AOJ 2102】Rummy

問題

Rummy | Aizu Online Judge

方針

  • 数字と記号のペアが与えられるので, 全通り試してセットであるか試す.
  • セットである条件は
    1. 3枚とも同じ色であること
    2. 番号がすべて同じか連番になっていること(ただし, 8, 9, 1のような連番は認められない)
  • これが3枚3セットになっているか判定する.

コード

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<ctime>
#include<cctype>
#include<climits>
#include<iostream>
#include<string>
#include<vector>
#include<map>
#include<list>
#include<queue>
#include<deque>
#include<algorithm>
#include<numeric>
#include<utility>
#include<complex>
#include<memory>
#include<functional>

#define rep(i, n) REP(i, 0, n)
#define REP(i, a, n) for(int i = a ; i < (int)n ; i++)
#define mp make_pair

using namespace std;

typedef pair<int, string> pis;

int n;
pair<int, string> v[9];
int num[9];
string mark[9];

bool check_num(pis a, pis b, pis c){
  if(a.first > b.first) swap(a, b);
  if(a.first > c.first) swap(a, c);
  if(b.first > c.first) swap(b, c);
  return (a.first + 1 == b.first && b.first + 1 == c.first) || (a.first == b.first && b.first == c.first);
}

bool check_mark(pis a, pis b, pis c){
  return a.second == b.second && b.second == c.second;
}

bool check(){
  bool ret = true;
  rep(i, 3){
    ret &= (check_num(v[i*3], v[i*3+1], v[i*3+2]) && check_mark(v[i*3], v[i*3+1], v[i*3+2]));
  }
  return ret;
}

signed main(){
  bool flag;
  cin >> n;
  while(n--){
    flag = false;
    rep(i, 9) cin >> num[i];
    rep(i, 9){
      cin >> mark[i];
      v[i] = mp(num[i], mark[i]);
    }

    do{
      if(check()){
        cout << 1 << endl;
        flag = true;
        break;
      }
    }while(next_permutation(v, v+9));
    if(!flag) cout << 0 << endl;
  }
}