Count Cooling, Warming and Constant Periods
National Olympiad — Municipal round (2011 season)
Submission name: temperature.cpp
Problem summary
Convert four readings per day into an integer daily mean. Count maximal consecutive cooling, warming and constant periods among these daily means.
Input
N, followed by N rows of four integer temperature readings.
Output
Cooling-period count, warming-period count and constant-period count.
Constraints
3 ≤ N ≤ 365; each reading is between −20 and 50. Integer division truncates the daily mean toward zero.
Worked example
Input and output for the worked example discussed below.
Input
6 2 5 8 6 4 7 9 8 6 8 8 7 4 3 3 1 0 -1 -1 -2 -2 2 3 3
Output
1 2 1
Solution analysis
- First compute each day’s mean as the sum of its four readings divided by 4 using integer division. Then classify every adjacent pair: −1 for a decrease, +1 for an increase, and 0 for equality.
- A maximal trend period corresponds to one maximal run of equal comparison signs. Count a new period at the first adjacent comparison and whenever its sign differs from the previous sign. At a turning point two periods share their endpoint day, which is allowed.
- The sample daily means are 5,7,7,2,−1,1. Their comparison signs are +,0,−,−,+. These form two warming runs, one constant run and one cooling run, so the required output order is 1 2 1.
Why it works
A sequence of equal adjacent-comparison signs is exactly a consecutive strict cooling, strict warming or constant interval. Extending it is possible precisely when the next sign is equal. Thus maximal sign runs and maximal required periods are in bijection, and the sign-change scan counts them exactly.
Watch out. Count periods, not the number of decreasing or increasing day pairs. Constant means form their own runs. Use C++ integer division for the stated integer-part convention and preserve cooling/warming/constant output order.
Commented C++17 solution
An independently written complete program with standard headers.
#include<algorithm>
#include<array>
#include<cmath>
#include<iostream>
#include<limits>
#include<map>
#include<numeric>
#include<set>
#include<string>
#include<vector>
using namespace std;
int main(){
int days;
cin>>days;
int counts[3]={0,0,0};
int previousMean=0;
int previousSign=2;
for(int day=0;day<days;day++){
int sum=0;
for(int reading=0;reading<4;reading++){
int value;
cin>>value;
sum+=value;
}
int mean=sum/4;
if(day>0){
int sign=(mean>previousMean)-(mean<previousMean);
// A new comparison-sign run starts a new maximal period.
if(sign!=previousSign){
counts[sign+1]++;
}
previousSign=sign;
}
previousMean=mean;
}
cout<<counts[0]<<' '<<counts[2]<<' '<<counts[1]<<'\n';
}