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 D2010 · EasySimulation

Legal Parking Spaces

Autumn Tournament (2010)

Submission name: parking.cpp

Problem summary

Each character describes a five-metre street segment, with traffic moving left to right. D is a garage, B a bus stop, S a crossing, and - an otherwise empty space. A garage blocks itself; a bus stop blocks itself and the two preceding segments; a crossing blocks itself and its immediate predecessor and successor. Count legal parking spaces for every street.

Input

n, then n street strings.

Output

n space-separated parking counts.

Constraints

1 ≤ n ≤ 25; each street has 1–50 characters from D, B, S and -.

Worked example

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

Input

3
---B--S-D--S--
DDBDDBDDBDD
--S--S--S--S--

Output

4 0 2

Solution analysis

  1. Create one blocked flag per segment, initially false. Process every restriction independently; overlapping restrictions simply set the same flag again.
  2. A garage marks index i. A bus stop marks i-2 through i, because its forbidden ten metres are before the stop. A crossing marks i-1 through i+1. Clip these ranges to the street boundaries rather than indexing outside the array.
  3. Count only unblocked positions. Every non-dash character blocks its own position automatically. For the first sample street the remaining positions are 0-based indices 0, 4, 9 and 13, giving four spaces; the next two streets give zero and two.

Why it works

A segment is marked if and only if at least one listed parking restriction covers it. Therefore exactly the unmarked segments are legal, and counting them produces the required total.

Complexity: O(L) time and O(L) extra space per street of length L; every symbol marks at most three segments.

Watch out. The bus stop restriction is before the stop, not after it. Clip negative and oversized indices. Do not subtract counts independently because forbidden areas can overlap.

Commented C++17 solution

An independently written complete program with standard headers.

#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;
int main(){
    int streets;
    cin>>streets;
    for(int street=0;street<streets;++street){
        string plan;
        cin>>plan;
        int length=static_cast<int>(plan.size());
        vector<bool>blocked(length,false);
        for(int i=0;i<length;++i){
            if(plan[i]=='-'){
                continue;
            }
            int left=i;
            int right=i;
            if(plan[i]=='B'){
                left=i-2;
            }
            else if(plan[i]=='S'){
                left=i-1;
                right=i+1;
            }
            // Several restrictions may cover the same segment.
            for(int position=max(0,left);position<=min(length-1,right);++position){
                blocked[position]=true;
            }
        }
        int answer=0;
        for(bool forbidden:blocked){
            if(!forbidden){
                ++answer;
            }
        }
        if(street>0){
            cout<<' ';
        }
        cout<<answer;
    }
    cout<<'\n';
}

Source: Arena Olimpiici ↗