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 D2022 · MediumUnbounded dynamic programming

Positive Two-Coin Equation

National Olympiad — Municipal round (2022 season)

Submission name: equation.cpp

Problem summary

Count k∈[1,L] that cannot equal ax+by for positive integers x,y.

Input

a b L.

Output

The number of unrepresentable k.

Constraints

1≤a,b<1000; 1≤L<100000.

Worked example

Input and output for the worked example discussed below.

Input

2 3 7

Output

5

Solution analysis

  1. Positive coefficients require one copy of each denomination, so initialize reachability at a+b rather than zero.
  2. Scan totals upwards, adding a or b from reachable totals. Positive increments make every transition go to a later state, so one pass suffices.
  3. For2,3,7 only5 and7 are reachable. Values1,2,3,4,6 are not, giving5. If a+b>L, all L values fail.

Why it works

Every reachable state includes the mandatory copies. Conversely any valid representation can be built by adding its remaining copies from a+b.

Complexity: O(L) time and O(L) space with two transitions per total.

Watch out. Starting at zero would incorrectly permit a zero coefficient.

Commented C++17 solution

An independently written complete program with standard headers.

#include<iostream>
#include<vector>
using namespace std;
// Every reachable state includes the mandatory copies.
int main(){
    int a,b,limit;
    cin>>a>>b>>limit;
    vector<bool>possible(limit+1,false);
    if(a+b<=limit){
        possible[a+b]=true;
    }
    for(int x=1;x<=limit;x++){
        if(!possible[x]){
            continue;
        }
        if(x+a<=limit){
            possible[x+a]=true;
        }
        if(x+b<=limit){
            possible[x+b]=true;
        }
    }
    int answer=0;
    for(int x=1;x<=limit;x++){
        answer+=!possible[x];
    }
    cout<<answer<<'\n';
}

Source: Arena Olimpiici ↗