Skip to content

Commit 19778da

Browse files
committed
Complete CodeForces 835E The Penguins Game
1 parent b54c8f7 commit 19778da

File tree

4 files changed

+127
-0
lines changed

4 files changed

+127
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ easily understandable algorithms for learning purposes.
100100
- [827C DNA Evolution](codeforces/dna-evolution)
101101
- [830B Cards Sorting](codeforces/cards-sorting)
102102
- [833B The Bakery](codeforces/the-bakery)
103+
- [835E The Penguin's Game](codeforces/the-penguins-game)
103104

104105
## Geeks for Geeks
105106

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
CXX := g++
2+
CXXFLAGS := -std=c++14 -Wall -o out
3+
4+
default: out run
5+
6+
out: main.cpp
7+
$(CXX) $(CXXFLAGS) main.cpp
8+
9+
clean:
10+
$(RM) out
11+
12+
run:
13+
./out
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# README
2+
3+
[http://codeforces.com/problemset/problem/835/E](http://codeforces.com/problemset/problem/835/E)
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
#include <bits/stdc++.h>
2+
3+
using namespace std; // NOLINT
4+
5+
// The maximum number of bits we need to represent positions 1 ... n.
6+
constexpr int MAX_BITS = 10;
7+
8+
int n, x, y;
9+
10+
//
11+
// Queries the XOR of icicles with positions idxs.
12+
//
13+
int query(const vector<int>& idxs) {
14+
cout << "? " << idxs.size();
15+
for (int i : idxs)
16+
cout << " " << i;
17+
cout << endl << flush;
18+
19+
int z;
20+
cin >> z;
21+
assert(z != -1);
22+
23+
return z;
24+
}
25+
26+
//
27+
// Finds the position of a single special icicle in positions idxs.
28+
//
29+
int find_one(const vector<int>& idxs) {
30+
assert(!idxs.empty());
31+
32+
if (idxs.size() == 1) return idxs[0];
33+
34+
auto mid = idxs.begin() + idxs.size() / 2;
35+
vector<int> left(idxs.begin(), mid);
36+
37+
int z = query(left);
38+
39+
if ((left.size() % 2 == 0 && z != 0) || (left.size() % 2 == 1 && z == y))
40+
return find_one(left);
41+
42+
vector<int> right(mid, idxs.end());
43+
return find_one(right);
44+
}
45+
46+
//
47+
// Returns a set of positions with the i'th bit set to 1.
48+
//
49+
vector<int> idxs_with_bit(int i) {
50+
vector<int> idxs;
51+
int mask = 1 << i;
52+
53+
for (int p = 1; p <= n; p++)
54+
if ((mask & p) != 0)
55+
idxs.push_back(p);
56+
57+
return idxs;
58+
}
59+
60+
//
61+
// Returns the bits that the positions of the two special icicles differ in.
62+
//
63+
vector<int> find_diff_bits() {
64+
vector<int> diff;
65+
66+
for (int i = 1; i <= MAX_BITS; i++) {
67+
auto idxs = idxs_with_bit(i - 1);
68+
69+
if (idxs.empty()) continue;
70+
71+
auto z = query(idxs);
72+
73+
if ((idxs.size() % 2 == 0 && z != 0) || (idxs.size() % 2 == 1 && z == y))
74+
diff.push_back(i - 1);
75+
}
76+
77+
return diff;
78+
}
79+
80+
int main() {
81+
ios::sync_with_stdio(false);
82+
83+
cin >> n >> x >> y;
84+
85+
// 1. Find bits in positions of special icicles that are different.
86+
auto bits = find_diff_bits();
87+
assert(!bits.empty());
88+
89+
// 2. Search for single special icicle in a set of positions where a
90+
// differing bit is on. This way we guarantee only one special icicle in the
91+
// set.
92+
auto idxs = idxs_with_bit(bits[0]);
93+
int p = find_one(idxs);
94+
95+
// 3. Reconstruct the other icicle using the bits we know are different.
96+
int q = p;
97+
for (int i : bits) {
98+
// Clear the ith bit of q.
99+
q = q & ~(1 << i);
100+
101+
// Set to inverse of ith bit of p.
102+
if ((p & (1 << i)) == 0) q = q | (1 << i);
103+
}
104+
105+
if (p > q) swap(p, q);
106+
107+
cout << "! " << p << " " << q << endl;
108+
109+
return 0;
110+
}

0 commit comments

Comments
 (0)