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 D2011 · EasyString scanning

Four Case-Insensitive Word Tests

National Olympiad — Regional round (2011 season)

Submission name: letters.cpp

Problem summary

For n rows of four words and one target letter, count: column 1 words starting with it, column 2 words containing it, column 3 words containing it at least twice, and column 4 words ending with it. Ignore letter case.

Input

n and a lowercase Latin letter, followed by n rows of four Latin-letter words.

Output

Four counts in the specified column order.

Constraints

1 < n < 10000; each word has at most 50 characters.

Worked example

Input and output for the worked example discussed below.

Input

3 a
Ani Miraj Masa Bala
Taralej toto Dani Kana
ananas pile ananas Tapa

Output

2 1 2 3

Solution analysis

  1. Process each column according to its own predicate. Convert every word to lowercase first, so uppercase A and lowercase a are treated identically.
  2. For columns 1 and 4 inspect the first or last character. For columns 2 and 3 count occurrences, then compare the count with 1 or 2. Increment the result once per qualifying word, not once per matching character.
  3. In the example, Ani and ananas start with a; only Miraj in column 2 contains a; Masa and ananas in column 3 have at least two; all three column-4 words end in a. The output is 2 1 2 3.

Why it works

Lowercasing preserves exactly case-insensitive equality. Each word is checked against its column’s stated condition, and contributes one if and only if that condition holds. Summing these indicators gives the four required word counts.

Complexity: O(total characters) time and O(maximum word length) auxiliary space; only one word is needed at a time.

Watch out. Do not count individual occurrences as words. Apply the predicates to their proper columns. Cast to unsigned char before tolower to avoid undefined behavior for negative char values.

Commented C++17 solution

An independently written complete program with standard headers.

#include<algorithm>
#include<cctype>
#include<iostream>
#include<string>
using namespace std;
int main(){
    int n;
    char target;
    cin>>n>>target;
    int answer[4]={};
    for(int row=0;row<n;row++){
        for(int column=0;column<4;column++){
            string word;
            cin>>word;
            for(char&letter:word){
                letter=char(tolower(static_cast<unsigned char>(letter)));
            }
            int occurrences=count(word.begin(),word.end(),target);
            // Each column tests a word once, not once per matching letter.
            bool valid=column==0?word.front()==target
                :column==1?occurrences>=1
                :column==2?occurrences>=2
                                    :word.back()==target;
            answer[column]+=valid;
        }
    }
    cout<<answer[0]<<' '<<answer[1]<<' '<<answer[2]<<' '<<answer[3]<<'\n';
}

Source: Arena Olimpiici ↗