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 D2012 · MediumStrings

Recover Page Numbers

Autumn Tournament (2012)

Submission name: number.cpp

Problem summary

A broken printer concatenates the page number i and the book’s total page count n. Count splits of the digit string into two nonempty decimal numbers satisfying 1≤i≤n. Neither number may have leading zeros.

Input

One digit string.

Output

The number of valid split positions.

Constraints

String length 1–200000.

Worked example

Original statement sample, with whitespace restored where PDF extraction merges adjacent numbers.

Input

23507645

Output

3

Solution analysis

  1. Never convert the long string into an integer. With no leading zeros, a shorter decimal representation is always smaller, and equal-length representations can be compared lexicographically.
  2. Let leftLength be the split position and rightLength the remaining length. Reject a split if either number begins with 0. If leftLength<rightLength, accept it; if leftLength>rightLength, reject it. Only an exactly central split can have equal lengths, so a character-by-character comparison is needed at most once.
  3. For 23507645, the splits after 2 and 23 are valid because the left part is shorter. The split after 235 is invalid because the right part begins with zero. The central split 2350|7645 is valid by lexicographic comparison. All later splits have a longer left part, so the total is three.

Why it works

Every split is considered once. Positive decimal numbers without leading zeros are ordered first by length, then lexicographically when their lengths agree. The accepted splits are therefore exactly those satisfying i≤n.

Complexity: O(L) time and O(L) input storage. There are L-1 constant-time split checks and at most one comparison of O(L) characters; only O(1) auxiliary space is needed.

Watch out. A leading zero on either side is forbidden, including a one-character zero because page numbers must be positive. The two parts must be nonempty. Do not compare different-length numbers lexicographically or use fixed-width integers for the numbers.

Commented C++17 solution

An independently written complete program with standard headers.

#include<iostream>
#include<string>
using namespace std;
int main(){
    string digits;
    cin>>digits;
    int length=static_cast<int>(digits.size());
    int answer=0;
    if(digits[0]!='0'){
        for(int split=1;split<length;++split){
            if(digits[split]=='0'){
                continue;
            }
            int rightLength=length-split;
            bool valid=split<rightLength;
            if(split==rightLength){
                // Equal lengths occur only at the central split.
                valid=digits.compare(0,split,digits,split,rightLength)<=0;
            }
            if(valid){
                ++answer;
            }
        }
    }
    cout<<answer<<'\n';
}

Source: Arena Olimpiici ↗