// Krzysztof Małysa #include <bits/stdc++.h> using namespace std; #define FOR(i,a,n) for (int i = (a), i##__ = (n); i <= i##__; ++i) #define REP(i,n) FOR(i,0,n-1) #define FORD(i,a,n) for (int i = (a), i##__ = (n); i >= i##__; --i) #define ALL(x) x.begin(), x.end() #define EB emplace_back #define ST first #define ND second #define OO(A) template<class... T> ostream& operator<<(ostream& os, const A<T...>& x) { return __o(os, ALL(x)); } #define SZ(x) ((int)x.size()) typedef long long LL; typedef pair<int, int> PII; typedef vector<int> VI; typedef vector<VI> VVI; typedef vector<PII> VPII; template<class A, class B> ostream& operator<<(ostream&, const pair<A, B>&); template<class I> ostream& __o(ostream&, I, I); template<class T, size_t N> ostream& operator<<(ostream& os, const array<T, N>& x) { return __o(os, ALL(x)); } OO(vector) OO(deque) OO(set) OO(multiset) OO(map) OO(multimap) template<class A, class B> ostream& operator<<(ostream& os, const pair<A, B>& p) { return os << "(" << p.ST << ", " << p.ND << ")"; } template<class I> ostream& __o(ostream& os, I a, I b) { os << "{"; for (; a != b;) os << *a++, cerr << (a == b ? "" : " "); return os << "}"; } template<class I> ostream& __d(ostream& os, I a, I b) { os << "{\n"; for (I c = a; a != b; ++a) os << " " << distance(c, a) << ": " << *a << endl; return os << "}"; } template<class... T> void __e(T&&... a) { int t[] = {(cerr << forward<T>(a), 0)...}; (void)t; cerr << endl; } template<class A, class B> void mini(A& a, B&& b) { if (b < a) a = b; } template<class A, class B> void maxi(A& a, B&& b) { if (b > a) a = b; } int ceil2(int x) { return 1 << (sizeof(x) * 8 - __builtin_clz(x - 1)); } #ifdef DEBUG # define D(...) __VA_ARGS__ #else # define D(...) #endif #define LOG(x) D(cerr << #x ": " << x) #define LOGN(x) D(LOG(x) << endl) #define DUMP(x) D(cerr << #x ": ", __d(cerr, ALL(x)) << endl) #define E(...) D(__e(__VA_ARGS__)) #define endl '\n' constexpr char nl = '\n'; // End of templates int n; vector<vector<bool>> a, b; inline int set_bit_id(int mask) { return sizeof(mask) * 8 - __builtin_clz(mask) - 1; } bool solve1(int amask, int bmask, int k = 1) { if (k == 2 * n - 1) { assert(__builtin_popcount(amask) == 1); assert(__builtin_popcount(bmask) == 1); return a[set_bit_id(amask)][set_bit_id(bmask)]; } bool res = false; // not-winning, will be true if a losing position is reachable if (k & 1) { // first moves REP (i, n) if (bmask & (1 << i)) res |= !solve1(amask, bmask ^ (1 << i), k + 1); } else { // second moves REP (i, n) if (amask & (1 << i)) res |= !solve1(amask ^ (1 << i), bmask, k + 1); } return res; } bool solve2(int amask, int bmask, int k = 1) { if (k == 2 * n - 1) { assert(__builtin_popcount(amask) == 1); assert(__builtin_popcount(bmask) == 1); return b[set_bit_id(amask)][set_bit_id(bmask)]; } bool res = false; // not-winning, will be true if a losing position is reachable if (k & 1) { // first moves REP (i, n) if (bmask & (1 << i)) res |= !solve2(amask, bmask ^ (1 << i), k + 1); } else { // second moves REP (i, n) if (amask & (1 << i)) res |= !solve2(amask ^ (1 << i), bmask, k + 1); } return res; } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int z; cin >> z; while (z--) { int m; cin >> n >> m; a.assign(n, vector<bool>(n)); b.assign(n, vector<bool>(n)); while (m--) { int x, y; char c; cin >> x >> c >> y; --x;--y; // Mark only winning edges if (c == '>') a[x][y] = true; else b[x][y] = true; } if (solve1((1 << n) - 1, (1 << n) - 1)) puts("WYGRANA"); else if (solve2((1 << n) - 1, (1 << n) - 1)) puts("PRZEGRANA"); else puts("REMIS"); } return 0; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 | // Krzysztof Małysa #include <bits/stdc++.h> using namespace std; #define FOR(i,a,n) for (int i = (a), i##__ = (n); i <= i##__; ++i) #define REP(i,n) FOR(i,0,n-1) #define FORD(i,a,n) for (int i = (a), i##__ = (n); i >= i##__; --i) #define ALL(x) x.begin(), x.end() #define EB emplace_back #define ST first #define ND second #define OO(A) template<class... T> ostream& operator<<(ostream& os, const A<T...>& x) { return __o(os, ALL(x)); } #define SZ(x) ((int)x.size()) typedef long long LL; typedef pair<int, int> PII; typedef vector<int> VI; typedef vector<VI> VVI; typedef vector<PII> VPII; template<class A, class B> ostream& operator<<(ostream&, const pair<A, B>&); template<class I> ostream& __o(ostream&, I, I); template<class T, size_t N> ostream& operator<<(ostream& os, const array<T, N>& x) { return __o(os, ALL(x)); } OO(vector) OO(deque) OO(set) OO(multiset) OO(map) OO(multimap) template<class A, class B> ostream& operator<<(ostream& os, const pair<A, B>& p) { return os << "(" << p.ST << ", " << p.ND << ")"; } template<class I> ostream& __o(ostream& os, I a, I b) { os << "{"; for (; a != b;) os << *a++, cerr << (a == b ? "" : " "); return os << "}"; } template<class I> ostream& __d(ostream& os, I a, I b) { os << "{\n"; for (I c = a; a != b; ++a) os << " " << distance(c, a) << ": " << *a << endl; return os << "}"; } template<class... T> void __e(T&&... a) { int t[] = {(cerr << forward<T>(a), 0)...}; (void)t; cerr << endl; } template<class A, class B> void mini(A& a, B&& b) { if (b < a) a = b; } template<class A, class B> void maxi(A& a, B&& b) { if (b > a) a = b; } int ceil2(int x) { return 1 << (sizeof(x) * 8 - __builtin_clz(x - 1)); } #ifdef DEBUG # define D(...) __VA_ARGS__ #else # define D(...) #endif #define LOG(x) D(cerr << #x ": " << x) #define LOGN(x) D(LOG(x) << endl) #define DUMP(x) D(cerr << #x ": ", __d(cerr, ALL(x)) << endl) #define E(...) D(__e(__VA_ARGS__)) #define endl '\n' constexpr char nl = '\n'; // End of templates int n; vector<vector<bool>> a, b; inline int set_bit_id(int mask) { return sizeof(mask) * 8 - __builtin_clz(mask) - 1; } bool solve1(int amask, int bmask, int k = 1) { if (k == 2 * n - 1) { assert(__builtin_popcount(amask) == 1); assert(__builtin_popcount(bmask) == 1); return a[set_bit_id(amask)][set_bit_id(bmask)]; } bool res = false; // not-winning, will be true if a losing position is reachable if (k & 1) { // first moves REP (i, n) if (bmask & (1 << i)) res |= !solve1(amask, bmask ^ (1 << i), k + 1); } else { // second moves REP (i, n) if (amask & (1 << i)) res |= !solve1(amask ^ (1 << i), bmask, k + 1); } return res; } bool solve2(int amask, int bmask, int k = 1) { if (k == 2 * n - 1) { assert(__builtin_popcount(amask) == 1); assert(__builtin_popcount(bmask) == 1); return b[set_bit_id(amask)][set_bit_id(bmask)]; } bool res = false; // not-winning, will be true if a losing position is reachable if (k & 1) { // first moves REP (i, n) if (bmask & (1 << i)) res |= !solve2(amask, bmask ^ (1 << i), k + 1); } else { // second moves REP (i, n) if (amask & (1 << i)) res |= !solve2(amask ^ (1 << i), bmask, k + 1); } return res; } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int z; cin >> z; while (z--) { int m; cin >> n >> m; a.assign(n, vector<bool>(n)); b.assign(n, vector<bool>(n)); while (m--) { int x, y; char c; cin >> x >> c >> y; --x;--y; // Mark only winning edges if (c == '>') a[x][y] = true; else b[x][y] = true; } if (solve1((1 << n) - 1, (1 << n) - 1)) puts("WYGRANA"); else if (solve2((1 << n) - 1, (1 << n) - 1)) puts("PRZEGRANA"); else puts("REMIS"); } return 0; } |