cppAcademy
FROM LEARNING TO COMPETING

Proficient.
Put your skills to the test.

Bulgarian Informatics Group B · 2007–2026

274 independently explained problems: 54 Municipal, 54 Regional, 109 National Olympiad and 57 Autumn Tournament tasks. Difficulty labels are learning estimates, not official ratings. Some events share Junior/IATI or Group A/B problem sets. Special formats, scoring limitations and source clarifications are explained on affected tasks. The two previously featured Autumn problems keep their existing permanent URLs.
GROUP B2009 · EasyInversions and parallel swaps

Parallel Handshakes

Autumn Tournament (2009)

Submission name: handshakes.cpp

Problem summary

People stand in a row facing left (L) or right (R). Each second, every adjacent RL pair shakes hands and both people turn, changing RL into LR simultaneously. Find the number of seconds until no handshake is possible and the total number of handshakes.

Input

One nonempty string of L and R characters.

Output

Time and total handshakes, separated by a space. The source also names NEVEREND for an infinite process; this cannot occur for a finite valid row.

Constraints

String length is at most 100000.

Worked example

Original statement sample.

Input

RLLRLRR

Output

3 4

Solution analysis

  1. Think of a right-facing person as a token moving right across left-facing people. Every R before an L forms one inversion, and they eventually shake hands exactly once. While scanning, count previous R characters; each L contributes that count to the total.
  2. For the time, maintain seconds for the processed prefix. An L with r previous R characters needs at least r seconds to cross them. If earlier left-facing people are already moving, it may also need one second after their completion. Therefore update seconds=max(seconds+1,r) when r>0.
  3. For RLLRLRR, the first two L characters have one R before them, contributing 1+1 handshakes and finishing after seconds 1 and 2. The third L has two R characters before it, contributes 2 more, and finishes at max(3,2)=3. Hence output 3 4.

Why it works

Each RL→LR exchange removes exactly one inversion and creates none, so infinitely many rounds are impossible. A left-facing token must wait for its preceding right-facing tokens and for the token ahead of it; these give the two terms in the completion-time recurrence. Once these constraints are met, every adjacent pair acts immediately, so the bound is attained.

Complexity: O(N) time and O(1) auxiliary space beyond the input string. The total can be about N²/4 and must use long long; the time is at most N−1.

Watch out. Do not update the string in place to simulate a simultaneous second: doing so can move a person multiple times. If there is no earlier R, an L creates no delay. Use 64-bit inversion totals.

Commented C++17 solution

An independently written complete program with standard headers.

#include<algorithm>
#include<iostream>
#include<string>
using namespace std;
int main(){
    string row;
    cin>>row;
    long long rightCount=0;
    long long handshakes=0;
    long long seconds=0;
    for(char facing:row){
        if(facing=='R'){
            rightCount++;
        }
        else if(rightCount>0){
            handshakes+=rightCount;
            // Account for both crossings and the token immediately ahead.
            seconds=max(seconds+1,rightCount);
        }
    }
    cout<<seconds<<' '<<handshakes<<'\n';
}

Source: Arena Olimpiici ↗