cppAcademy
FROM LEARNING TO COMPETING

Intermediate.
Put your skills to the test.

Bulgarian Informatics Group D · 2007–2026

270 independently explained problems: 54 Municipal, 54 Regional, 105 National Olympiad and 57 Autumn Tournament tasks. Start with the easier tasks and work upwards. Difficulty labels are learning estimates, not official ratings; Group D also includes challenging national-level problems. The six 2017 National tasks shared by Groups C and D use their existing permanent URLs. Years follow Arena’s competition-season labels. Source clarifications and special grader requirements are noted on affected tasks.
GROUP D2016 · EasyBounded enumeration

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

  1. 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.
  2. 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.
  3. 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.
  4. 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.

Complexity: O(12·min(N,99)) time, bounded by 1080 checks, and O(12) space for the monthly counts and first candidates. All concatenated numbers have five digits and fit in int.

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';
    }
}

Source: Arena Olimpiici ↗