Sherlock Holmes Volumes
Autumn Tournament (2016)
Submission name: sherlok.cpp
Problem summary
There are N volumes numbered 1 through N. For each month m, choose N1=m+10, N2=s, and a third volume N3 that is not one-digit and is not any month plus 10. Concatenating N1,N2,N3 must give a five-digit number divisible by at least one of N1+N2, N1+N3, N2+N3. Count choices for every month; for the requested month M, also print a valid triple with smallest N3, or three zeros if none exists.
Input
Three integers N, s, M.
Output
Twelve lines containing the counts for months 1 through 12, followed by the selected triple for month M, or 0 0 0.
Constraints
23 ≤ N ≤ 9999; 1 ≤ s ≤ 9; 1 ≤ M ≤ 12.
Worked example
Original statement sample.
Input
99 3 3
Output
10 8 7 6 4 8 4 5 3 8 5 5 13 3 28
Solution analysis
- N1 has exactly two digits and s has one. Therefore the five-digit requirement forces N3 to have exactly two digits, even when N is much larger than 99. Try 10 through min(N,99), excluding 11 through 22 because those are month numbers plus 10. Volume 10 is allowed.
- For each month, construct the concatenated value arithmetically as N1·1000+s·100+N3. Check the three possible pair sums using modulo. A candidate that passes several divisibility tests still counts only once.
- Scan N3 in increasing order, count every accepted value, and remember only the first accepted candidate for each month. For N=99, s=3, M=3, the chosen N3 is 28: 13328 is divisible by 13+3=16. Month 3 has seven valid choices.
- There are at most 90 candidates per month, so direct enumeration is simpler than trying to derive a number-theory formula. The selected volumes are automatically distinct: N1 lies in 11–22, s in 1–9, and N3 lies outside both ranges.
Why it works
The digit-length argument enumerates precisely all possible third-volume numbers. Removing 11–22 enforces the remaining prohibition. The three modular tests are exactly the allowed divisibility alternatives. Therefore each valid triple is counted once and no invalid triple is counted. Increasing candidate order ensures the stored third volume is the smallest.
Watch out. N3=10 is legal. Exclude every month-plus-10 value, not just the current month’s N1. Do not count a candidate multiple times if more than one pair sum divides its number. N up to 9999 does not allow a three- or four-digit N3.
Commented C++17 solution
An independently written complete program with standard headers.
// Key idea: The digit-length argument enumerates precisely all possible third-volume numbers. Removing
// 11–22 enforces the remaining prohibition.
#include<algorithm>
#include<array>
#include<iostream>
using namespace std;
int main(){
int volumes;
int secret;
int currentMonth;
cin>>volumes>>secret>>currentMonth;
array<int,13>count{};
array<int,13>firstThird{};
for(int month=1;month<=12;++month){
int first=month+10;
for(int third=10;third<=min(volumes,99);++third){
if(third>=11&&third<=22){
continue;
}
int number=first*1000+secret*100+third;
bool valid=number%(first+secret)==0;
valid=valid||number%(first+third)==0;
valid=valid||number%(secret+third)==0;
if(valid){
++count[month];
if(firstThird[month]==0){
firstThird[month]=third;
}
}
}
cout<<count[month]<<'\n';
}
if(firstThird[currentMonth]==0){
cout<<"0 0 0\n";
}
else{
cout<<currentMonth+10<<' '<<secret<<' ';
cout<<firstThird[currentMonth]<<'\n';
}
}