#include <iostream>
#include <vector>
#include <map>
#include <stack>
#define REP(i, n) for(int i=0; i<(int)n; ++i)
#define FOR(i, c) for(__typeof((c).begin())i=(c).begin(); i!=(c).end(); ++i)
#define ALL(c) (c).begin(),(c).end()
using namespace std;
class DisjointSet{
public:
vector<int> rank, p;
DisjointSet(){}
DisjointSet(int size){
rank.resize(size, 0);
p.resize(size, 0);
}
void make(int a){
rank[a] = 0;
p[a] = a;
}
void join(int a, int b){
link(find(a), find(b));
}
int find(int a){
return (a == p[a])? a : p[a] = find(p[a]);
}
bool isSameSet(int a, int b){
return find(a) == find(b);
}
void link (int a, int b){
if(rank[a] > rank[b]) p[b] = a;
else{
p[a] = b;
if(rank[a] == rank[b]) rank[b]++;
}
}
};
pair<int, int> sep[12];
int no[4][4][4][4];
class State{
public:
DisjointSet ds;
int bit;
State(){
bit = (1 << 12) - 1;
ds = DisjointSet(9);
for(int i=0; i<9; ++i) ds.make(i);
return ;
}
bool is_connected(int a, int b){
return ds.isSameSet(a, b);
}
void remove_bar(int n){
bit ^= (1 << n);
ds.join( sep[n].first, sep[n].second );
return ;
}
bool is_remained(int n){
return bit & (1 << n);
}
};
void init(void)
{
sep[0] = make_pair(0, 1);
sep[1] = make_pair(1, 2);
sep[2] = make_pair(0, 3);
sep[3] = make_pair(1, 4);
sep[4] = make_pair(2, 5);
sep[5] = make_pair(3, 4);
sep[6] = make_pair(4, 5);
sep[7] = make_pair(3, 6);
sep[8] = make_pair(4, 7);
sep[9] = make_pair(5, 8);
sep[10] = make_pair(6, 7);
sep[11] = make_pair(7, 8);
#define ref_no(a, b, c, d) no[a][b][c][d] = no[c][d][a][b]
ref_no(1, 0, 1, 1) = 0;
ref_no(2, 0, 2, 1) = 1;
ref_no(0, 1, 1, 1) = 2;
ref_no(1, 1, 2, 1) = 3;
ref_no(2, 1, 3, 1) = 4;
ref_no(1, 1, 1, 2) = 5;
ref_no(2, 1, 2, 2) = 6;
ref_no(0, 2, 1, 2) = 7;
ref_no(1, 2, 2, 2) = 8;
ref_no(2, 2, 3, 2) = 9;
ref_no(1, 2, 1, 3) = 10;
ref_no(2, 2, 2, 3) = 11;
return ;
}
const int W = 0, L = 1;
const int T = 1 << 12;
int t[T];
int rec(State s, const int M, const int C)
{
if( s.is_connected(M, C) )return L;
if( t[ s.bit ] != -1 )return t[ s.bit ];
State tmp = s;
int r = L;
for(int i=0; i<12; ++i){
if( !s.is_remained(i) )continue;
s.remove_bar(i);
r = min( r, rec(s, M, C)^1 );
s = tmp;
}
return t[ s.bit ] = r;
}
int main(void)
{
init();
int tc, cnt = 0;
cin >> tc;
while( tc-- ){
fill( t, t + T, -1 );
int m, c, b;
State s;
cin >> m >> c >> b;
--m; --c;
while( b-- ){
int i, j, k, l;
cin >> i >> j >> k >> l;
s.remove_bar( no[i][j][k][l] );
}
cout << "Case " << ++cnt << ": " << flush;
if( s.is_connected(m, c) ) cout << "No Cheese!" << endl;
else cout << ( rec(s, m, c) == W ? "SOHA" : "TARA" ) << endl;
}
return 0;
}
5/24/2011
UVa11818
登録:
コメントの投稿
(
Atom
)
0 件のコメント :
コメントを投稿