/* ID: espr1t LANG: C++ TASK: Demo CONTEST: CodeIT, Round 2, 2011 KEYWORDS: */ #include #include #include #include #include #include #include #include #include #include #include #include #define MAX 1024 using namespace std; FILE *in; FILE *out; int n, m, k, h; int a[MAX][MAX], parity[MAX]; int cols[MAX]; inline int popcount(unsigned long long mask) { int ans = 0; while (mask) {ans++; mask &= (mask - 1);} return ans; } int cntt = 0; vector < pair > q, q1, q2; void recurse(int idx, int midx, int rem, unsigned long long mask, unsigned long long used) { if (idx >= midx) { q.push_back(make_pair(mask, used)); return; } // Don't use recurse(idx + 1, midx, rem, mask, used); // Use if (rem > 0) { unsigned long long nmask = mask; for (int i = 0; i < n; i++) if (a[i][cols[idx]]) nmask ^= ((unsigned long long)1 << i); recurse(idx + 1, midx, rem - 1, nmask, used | ((unsigned long long)1 << cols[idx])); } } void makeClean(vector < pair >& q, vector < pair >& at) { if (q.empty()) return; else sort(q.begin(), q.end()); unsigned long long last = q[0].first; at.push_back(q[0]); for (int i = 1; i < (int)q.size(); i++) { if (q[i].first != last) { last = q[i].first; at.push_back(q[i]); } else { if (popcount(at.back().second) > popcount(q[i].second)) at.back().second = q[i].second; } } } int bsearch(vector < pair >& v, unsigned long long val) { int left = 0, right = (int)v.size() - 1; while (left <= right) { int mid = (left + right) / 2; if (v[mid].first == val) return mid; if (v[mid].first < val) left = mid + 1; else right = mid - 1; } return -1; } int main(void) { in = stdin; out = stdout; in = fopen("bits.in", "rt"); out = fopen("bits.out", "wt"); // unsigned sTime = clock(); fscanf(in, "%d %d", &n, &k); char buff[MAX]; for (int i = 0; i < n; i++) { fscanf(in, "%s %d", buff, &parity[i]); m = (int)strlen(buff); for (int c = 0; c < m; c++) a[i][c] = buff[c] - '0'; } unsigned long long mask = 0; for (int i = 0; i < n; i++) if (parity[i]) mask |= ((unsigned long long)1 << i); for (int i = 0; i < m; i++) cols[i] = i; random_shuffle(cols, cols + m); h = m / 2; recurse(0, h, min(8, k), 0, 0); // fprintf(stderr, "Execution time here is %.3lf\n", (double)(clock() - sTime) / CLOCKS_PER_SEC); makeClean(q, q1); q.clear(); // fprintf(stderr, "Execution time here is %.3lf\n", (double)(clock() - sTime) / CLOCKS_PER_SEC); recurse(h, m, min(8, k), 0, 0); // fprintf(stderr, "Execution time here is %.3lf\n", (double)(clock() - sTime) / CLOCKS_PER_SEC); makeClean(q, q2); q.clear(); // fprintf(stderr, "Execution time here is %.3lf\n", (double)(clock() - sTime) / CLOCKS_PER_SEC); int ans = -1; unsigned long long ansMask = 0; for (int i = 0; i < (int)q1.size(); i++) { int cnt = popcount(q1[i].second); unsigned long long nmask = mask ^ q1[i].first; int idx = bsearch(q2, nmask); if (idx != -1) { int ocnt = popcount(q2[idx].second); if (cnt + ocnt <= k && ans < cnt + ocnt) { ans = cnt + ocnt; ansMask = q1[i].second | q2[idx].second; if (ans == k) break; } } } fprintf(out, "%d\n", ans); vector v; for (int i = 0; i < n; i++) if (ansMask & ((unsigned long long)1 << i)) v.push_back(i); for (int i = 0; i < (int)v.size(); i++) fprintf(out, "%d%c", v[i], i + 1 == (int)v.size() ? '\n' : ' '); return 0; }