Longest Nondecreasing Price Run
National Olympiad — Regional round (2011 season)
Submission name: seq.cpp
Problem summary
Find the maximum number of consecutive prices that never decrease. The positive price stream ends with a zero sentinel; there is no initial count.
Input
Positive prices separated by whitespace, terminated by 0.
Output
The length of the longest contiguous nondecreasing run.
Constraints
The source places no fixed bound on the number of prices. Prices are positive; 0 terminates input.
Worked example
Input and output for the worked example discussed below.
Input
2.12 2.15 2.15 2.14 2.10 2.21 2.21 2.28 2.25 2.26 0
Output
4
Solution analysis
- A nondecreasing run can extend to the next price exactly when next≥previous. A decrease destroys that extension, so the best run ending at the new price starts over with length 1.
- Read until the sentinel rather than trying to infer a row length. Keep previous, the current run length, and the best length seen. Equal consecutive prices extend the run. The sentinel is not a price and must not enter the comparison.
- The sample’s longest block is 2.10,2.21,2.21,2.28, of length 4. This is a contiguous block, not an arbitrary subsequence chosen from separated positions.
Why it works
Inductively, the current counter is the longest valid run ending at the last processed price: it extends by one on a nondecrease and is exactly one on a decrease. Every possible best run ends somewhere in the stream, so the maximum of these counters is the requested answer.
Watch out. Do not count the terminating zero, reset on equality, or solve the different longest-nondecreasing-subsequence problem. Use a real type for prices rather than truncating them to integers.
Commented C++17 solution
An independently written complete program with standard headers.
#include<algorithm>
#include<iostream>
using namespace std;
int main(){
long double value;
long double previous=0;
long long run=0;
long long best=0;
while(cin>>value&&value!=0){
// Equality is allowed; only a strict decrease starts a new run.
run=run>0&&value>=previous?run+1:1;
best=max(best,run);
previous=value;
}
cout<<best<<'\n';
}