Search for a command to run...
Progressive hints first, then the full explanation and implementation when you're ready to cash out.
Review status
AI-generated and still unreviewed. Double-check the details before internalizing them.
Hints
Open only as much as you need to keep the solve alive.
A query with many equal word lengths is the cleanest measurement. If you ask for copies of length , then each line holds words, unless .
In the easy version, querying copies of gives . That pins to an interval , and the important property is .
Once and the interval satisfies , pairs can test thresholds independently: the pair fits exactly when , and neighboring pairs cannot accidentally merge.
For the hard version, replace the first query by copies of . The answer becomes if , otherwise , which gives a scaled interval for .
Use constants found by brute force: , . Then the first query costs , the low- fallback costs , and every remaining interval is short enough for the pair trick. The budget survives by a few hundred words. Classic CF nonsense, but legal.
This is interactive, so the real goal is not to compute from input. The goal is to design at most two articles whose returned line counts force the value of .
Equal Words
Suppose we query an article with copies of one word length .
If , the editor cannot display the article, so the answer is .
Otherwise, one line can contain exactly
words, so the answer is
For a fixed nonzero answer , the possible values of form an interval:
Using integer division:
Since , this gives
Also cap by .
A key fact: this interval is shaped nicely. In the -interval, we have . If not, then would still be inside the interval, but
contradiction. After scaling, this gives enough room to isolate the second query.
Resolving An Interval
Now assume we know . Let
If , then a word of length is too large, so any query containing returns . That handles the left endpoint cleanly.
For every threshold
put this pair into the second article:
The pair sum is exactly , so it fits on one line exactly when .
The pairs do not interfere with each other. Because , after a fitting pair, the next cannot join the same line. If a pair does not fit, then its second word plus the next has sum , so that also cannot join. Good: each pair acts independently instead of turning into wrapping soup.
Let
be the number of pairs, and let the second answer be .
If , then .
Otherwise, the number of fitting pairs is
Each fitting pair uses line, and each non-fitting pair uses lines, so
Therefore
The implementation uses the article length itself, , in that formula.
The Low Case
If the first query returns , then .
Use the second query as copies of . The answer is
For , these answers are all distinct, because for consecutive values:
So the ceilings strictly decrease. We recover
Constants
We need the total queried article length to be at most .
A working brute-forced choice is
Then:
Thus the worst case is
The manual hack format is for the interactor/test data. The contestant program still follows the interactive protocol: print queries, flush, read answers, and finally print ! W.
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
void setIO() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
}
const int MAXW = 100000;
const int B = 116;
const int N = 11343;
int ask(const vector<int>& a) {
cout << "? " << a.size();
for (int x : a) cout << ' ' << x;
cout << endl;
int res;
if (!(cin >> res)) exit(0);
if (res == -1) exit(0);
return res;
}
void answer(int w) {
cout << "! " << w << endl;
}
int main() {
setIO();
int t;
cin >> t;
while (t--) {
int r1 = ask(vector<int>(N, B));
if (r1 == 0) {
int r2 = ask(vector<int>(B * B, 1));
answer((B * B - 1) / (r2 - 1));
continue;
}
int L = ((N - 1) / r1 + 1) * B;
int R = ((N - 1) / (r1 - 1) + 1) * B - 1;
R = min(R, MAXW);
if (L == R) {
answer(L);
continue;
}
vector<int> q2;
for (int i = L + 2; i <= R; i++) {
q2.push_back(L + 1);
q2.push_back(i - L - 1);
}
if (q2.empty()) q2.push_back(L + 1);
int r2 = ask(q2);
if (r2 == 0) answer(L);
else answer(L + 1 + (int)q2.size() - r2);
}
return 0;
}#include <bits/stdc++.h>
using namespace std;
using ll = long long;
void setIO() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
}
const int MAXW = 100000;
const int B = 116;
const int N = 11343;
int ask(const vector<int>& a) {
cout << "? " << a.size();
for (int x : a) cout << ' ' << x;
cout << endl;
int res;
if (!(cin >> res)) exit(0);
if (res == -1) exit(0);
return res;
}
void answer(int w) {
cout << "! " << w << endl;
}
int main() {
setIO();
int t;
cin >> t;
while (t--) {
int r1 = ask(vector<int>(N, B));
if (r1 == 0) {
int r2 = ask(vector<int>(B * B, 1));
answer((B * B - 1) / (r2 - 1));
continue;
}
int L = ((N - 1) / r1 + 1) * B;
int R = ((N - 1) / (r1 - 1) + 1) * B - 1;
R = min(R, MAXW);
if (L == R) {
answer(L);
continue;
}
vector<int> q2;
for (int i = L + 2; i <= R; i++) {
q2.push_back(L + 1);
q2.push_back(i - L - 1);
}
if (q2.empty()) q2.push_back(L + 1);
int r2 = ask(q2);
if (r2 == 0) answer(L);
else answer(L + 1 + (int)q2.size() - r2);
}
return 0;
}