Equal Sums on Every Shortest Grid Path
National Olympiad — National round (2014 season)
Submission name: table.cpp
Problem summary
A side-adjacent top-left to bottom-right path visits exactly N+M−1 cells. Decide whether all such paths have equal sums.
Input
Up to ten tables: N M and N rows of M integers; terminate with 0 0.
Output
One line of Y/N characters, one per table.
Constraints
N,M≥1; NM≤30000; entries −33000…33000.
Worked example
Input and output for the worked example discussed below.
Input
2 3 1 2 3 2 3 4 3 3 2 1 3 6 1 3 4 4 5 0 0
Output
YN
Solution analysis
- A path of the specified minimum length uses only right and down moves. Compare right-down and down-right alternatives around any 2×2 square: their shared endpoints cancel from the sum.
- The alternatives agree exactly when the upper-right and lower-left entries are equal. Check this local condition for every 2×2 square. When all checks pass, every anti-diagonal is constant.
- Every shortest path visits one cell from each anti-diagonal, so those local equalities suffice. The first sample table has anti-diagonal values 1,2,3,4 and qualifies; the second has upper-right 1 unequal to lower-left 6 and fails.
Why it works
Any local square can be embedded in a shortest prefix and suffix, so equal global sums force the middle alternatives to match. Conversely, the local equalities make every anti-diagonal constant, and every shortest path takes one value from each. This proves equivalence.
Watch out. Only minimum-length paths count. A one-row or one-column table always qualifies. Compare upper-right with lower-left, not opposite corners.
Commented C++17 solution
An independently written complete program with standard headers.
#include<iostream>
#include<string>
#include<vector>
using namespace std;
int main(){
int rows;
int columns;
string answers;
while(cin>>rows>>columns&&(rows!=0||columns!=0)){
vector<vector<int>>grid(rows,vector<int>(columns));
for(auto&row:grid){
for(int&value:row){
cin>>value;
}
}
bool valid=true;
for(int r=1;r<rows;r++){
for(int c=1;c<columns;c++){
// Swapping right-down with down-right must preserve the sum.
if(grid[r-1][c]!=grid[r][c-1]){
valid=false;
}
}
}
answers+=valid?'Y':'N';
}
cout<<answers<<'\n';
}