Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <functional>
- #include <unordered_set>
- #include <algorithm>
- #include <iostream>
- #include <numeric>
- #include <cassert>
- #include <cstdlib>
- #include <string>
- #include <cstdio>
- #include <vector>
- #include <ctime>
- #include <queue>
- #include <set>
- #include <map>
- using namespace std;
- #define forn(i, n) for (int i = 0; i < (int)(n); ++i)
- #define fore(i, b, e) for (int i = (int)(b); i <= (int)(e); ++i)
- #define ford(i, n) for (int i = (int)(n) - 1; i >= 0; --i)
- #define mp make_pair
- #define pb push_back
- #define fi first
- #define se second
- #define all(x) (x).begin(), (x).end()
- typedef vector<int> vi;
- typedef pair<int, int> pii;
- typedef long long i64;
- typedef unsigned long long u64;
- const int inf = 1e9+100500;
- int n, m;
- i64 setbit(i64 x, int i, int j) {
- return x | 1ll<<(i*m+j);
- }
- vector<i64> vm;
- vector<i64> vh;
- bool cz[1<<20];
- void genmasks() {
- vm.clear();
- vh.clear();
- forn(i, 1<<n) {
- if (__builtin_popcount(i) <= 1) continue;
- i64 m = 0;
- forn(j, n) if (i&(1<<j)) m |= 1ll<<(j*::m);
- vm.pb(m);
- }
- forn(i, 1<<m) if (i) vh.pb(i);
- stable_sort(all(vm), [](int x, int y) { return __builtin_popcount(x) < __builtin_popcount(y); });
- forn(i, vm.size()) {
- if (i == 0 || __builtin_popcount(vm[i]) < __builtin_popcount(vm[i-1]))
- cz[i] = 1;
- else
- cz[i] = 0;
- }
- sort(all(vh), [](int x, int y) { return __builtin_popcount(x) < __builtin_popcount(y); });
- }
- void out(i64 x) {
- forn(i, n) {
- forn(j, m) cout << (0 != (x&1ll<<(i*m+j)));
- cout << endl;
- }
- cout << endl;
- }
- unordered_set<i64> win, lose;
- int a[20];
- i64 sort_cols(i64 mask) {
- forn(i, m) a[i] = 0;
- forn(i, n) {
- forn(j, m) a[j] = a[j]*2+(0 != (mask&(1<<j)));
- mask >>= m;
- }
- sort(a, a+m);
- forn(i, n) {
- mask <<= m;
- forn(j, m) {
- if (a[j] & 1) {
- mask |= 1<<j;
- }
- a[j] >>= 1;
- }
- }
- return mask;
- }
- i64 sort_mask(i64 mask) {
- forn(i, n) {
- a[i] = mask&((1ll<<m)-1);
- mask >>= m;
- }
- assert(mask == 0);
- sort(a, a+n, [](int x, int y) { return __builtin_popcount(x) < __builtin_popcount(y); });
- forn(i, n) {
- mask <<= m;
- mask ^= a[i];
- }
- return sort_cols(mask);
- }
- int go(i64 x) {
- x = sort_mask(x);
- if (win.count(x)) return 1;
- if (lose.count(x)) return 0;
- forn(i, vh.size()) forn(j, n) {
- if (x == 0) {
- if (j) break;
- if (vh[i]&(vh[i]+1)) break;
- }
- i64 t = (i64)vh[i]<<(j*m);
- if (x&t) continue;
- if (!go(x|t)) {
- win.insert(x);
- if (x == 0) {
- out(t);
- } else {
- return 1;
- }
- }
- }
- forn(i, vm.size()) forn(j, m) {
- if (x == 0) {
- if (j) break;
- if (!cz[i]) break;
- }
- i64 t = vm[i]<<j;
- if (x&t) continue;
- if (!go(x|t)) {
- win.insert(x);
- if (x == 0) {
- out(t);
- } else {
- return 1;
- }
- }
- }
- if (x == 0) return win.count(x);
- lose.insert(x);
- return 0;
- }
- int main() {
- #ifdef HOME
- // freopen("input.txt", "r", stdin);
- #endif
- clock_t ct;
- while (1) {
- cin >> n >> m;
- ct = clock();
- genmasks();
- win.clear();
- lose.clear();
- cout << go(0) << endl;
- cout << "Time: " << (clock() - ct) / 1000 << " ms" << endl;
- }
- #ifdef HOME
- cerr << "Time elapsed: " << clock() / 1000 << " ms" << endl;
- #endif
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment