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 D2017 · MediumArrays and matrices

Hide the Pencil

Autumn Tournament (2017)

Submission name: hidepencil.cpp

Problem summary

An N × M rectangular bundle contains vertical pencil cases of different heights, all standing on the same table. A pencil has height H. Count the cases in which the pencil cannot be seen from any of the four side views perpendicular to a side of the bundle. A case at least H tall hides the pencil itself; a shorter one needs shielding by other cases in all four directions.

Input

N M H, followed by N rows of M case heights.

Output

The number of positions that hide the pencil.

Constraints

All input values, including N, M, H and case heights, are positive integers at most 200.

Worked example

Official statement sample.

Input

3 4 5
7 7 4 4
6 3 7 3
6 7 6 2

Output

8

Solution analysis

  1. Consider a single row viewed from its left end. A pencil is hidden if a case of height at least H occurs at or before its position. Taller cases farther away do not help this view. The same test applies from the right, top, and bottom.
  2. Perform four sweeps. Keep a Boolean blocked flag, which becomes true when the sweep reaches a case of height at least H. For each position, record whether every view has remained hidden. Including the current case means a tall case passes all four tests automatically.
  3. In the sample, seven cases themselves reach height 5. The short case of height 3 in row 2, column 2 is also hidden: tall cases shield it from left, right, above, and below. The remaining short cases have an exposed direction, giving eight valid positions.

Why it works

In a fixed perpendicular view, cases in the same row or column are aligned. The pencil is invisible exactly when its own case or an intervening case reaches H. Each sweep tests this condition for one side. A position is counted precisely when all four necessary and sufficient side conditions hold.

Complexity: O(NM) time for four sweeps and the final count; O(NM) extra space for the heights and visibility flags.

Watch out. A tall case must count as its own shield. Reset the sweep flag for each row or column. Only the four perpendicular side views in the statement are tested, not a view from above.

Commented C++17 solution

An independently written complete program with standard headers.

// Key idea: In a fixed perpendicular view, cases in the same row or column are aligned. The pencil is
// invisible exactly when its own case or an intervening case reaches H.
#include<iostream>
#include<vector>
using namespace std;
int main(){
    int rows,columns,pencilHeight;
    cin>>rows>>columns>>pencilHeight;
    vector<vector<int>>height(rows,vector<int>(columns));
    vector<vector<bool>>hidden(rows,vector<bool>(columns,true));
    for(auto&row:height){
        for(int&value:row){
            cin>>value;
        }
    }
    for(int row=0;row<rows;row++){
        bool blocked=false;
        for(int column=0;column<columns;column++){
            blocked=blocked||height[row][column]>=pencilHeight;
            hidden[row][column]=hidden[row][column]&&blocked;
        }
        blocked=false;
        for(int column=columns-1;column>=0;column--){
            blocked=blocked||height[row][column]>=pencilHeight;
            hidden[row][column]=hidden[row][column]&&blocked;
        }
    }
    for(int column=0;column<columns;column++){
        bool blocked=false;
        for(int row=0;row<rows;row++){
            blocked=blocked||height[row][column]>=pencilHeight;
            hidden[row][column]=hidden[row][column]&&blocked;
        }
        blocked=false;
        for(int row=rows-1;row>=0;row--){
            blocked=blocked||height[row][column]>=pencilHeight;
            hidden[row][column]=hidden[row][column]&&blocked;
        }
    }
    int answer=0;
    for(const auto&row:hidden){
        for(bool positionHidden:row){
            if(positionHidden){
                answer++;
            }
        }
    }
    cout<<answer<<'\n';
}

Source: Arena Olimpiici ↗