Even Wins
National Olympiad — Regional round (2009 season)
Submission name: even.cpp
Problem summary
The computer chooses K and moves first. Starting with an odd number N of objects, players alternate taking between 1 and K objects. The player whose total number of taken objects is even wins. Output ten distinct odd N>3, each with at most 18 digits, for which the second player has a winning strategy.
Input
K.
Output
Any ten qualifying values of N separated by spaces.
Constraints
1 < K < 10^15; 3 < N < 10^18; N is odd.
Worked example
The official sample is one valid set of ten losing positions. The deterministic program prints 5 9 13 17 21 25 29 33 37 41, another valid set.
Input
2
Output
5 13 17 29 33 21 2221 101 37 25
Solution analysis
- Track the parity p of the current player’s collected objects as well as the remaining number n. Because the original total is odd, the opponent’s parity is q=(1−n−p) modulo 2. Let L(n,p) mean that the current player loses. Then L(0,0) is false and L(0,1) is true; for positive n, L(n,p) holds exactly when every legal t leads to a nonlosing state L(n−t,q)=false.
- Solving this recurrence gives a period P=K+2 for even K: losing residues for p=0 are {1}, and for p=1 are {0,K+1}. For odd K the period is P=2(K+1): losing residues for p=0 are {1,K+1}, and for p=1 are {0,K+2}. These residue descriptions can be checked directly in the recurrence.
- Both players initially have parity zero. Thus N=1+iP for i=1,...,10 always makes the first player lose. For K=2 this gives 5,9,13,...,41; the official sample lists another valid collection from the same residue class.
Why it works
The two terminal parity states express exactly who has an even total. For n>0, the current player loses iff every move lets the opponent win, yielding the stated recurrence. Substituting the displayed residue sets checks that a losing state has no losing successor and a winning state has at least one, including the shortened move range n<K; induction therefore establishes the formulas. Our N have losing residue 1 and parity p=0. P is even, so all outputs are odd and distinct, and 1+10P<2·10^16+21<10^18.
Watch out. This is a parity-of-collected-objects game, not last-move-wins. Output may differ from the example and still be correct.
Commented C++17 solution
An independently written complete program with standard headers.
#include<iostream>
using namespace std;
int main(){
long long k;
cin>>k;
// Residue 1 in the appropriate period loses for the first player.
long long period=k%2==0?k+2:2*(k+1);
for(int i=1;i<=10;i++){
if(i!=1){
cout<<' ';
}
cout<<1+i*period;
}
cout<<'\n';
}