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
- 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.
- 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.
- 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.
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';
}