Search for a command to run...
Progressive hints first, then the full explanation and implementation when you're ready to cash out.
Review status
AI-generated and still unreviewed. Double-check the details before internalizing them.
Hints
Open only as much as you need to keep the solve alive.
Ignore the messages completely. The only thing that matters is the sequence of times, and each real date must correspond to one contiguous block of records.
Convert every time to minutes from midnight in . Be very careful with : If you mess this up, the rest is toast.
Ask when a block can belong to a single day. Inside one day, timestamps must be nondecreasing, and any exact minute can appear at most times.
Because times inside one day are nondecreasing, equal minutes form one consecutive run. So a block is valid iff the converted times never decrease and no run of equal values has length . Now think about taking the longest valid prefix as one day.
Greedy is enough: scan left to right, keeping the current day's last minute and the length of the current equal-time run. If the next record has , or and the run is already , you must start a new day here. Count how many times this happens.
The messages are pure noise. After parsing the input, all that remains is a sequence of times where each is the minute of the day in .
A date in the original log cannot disappear and then come back later, because the full log was written in chronological order. So every date corresponds to one contiguous segment of the sequence. The whole problem is really:
Partition the sequence into the minimum number of contiguous blocks, where each block could be one day.
That is the whole game. No DP fireworks needed. Don't overengineer it.
Use
This handles the annoying cases correctly:
The sentence about midnight belonging to the coming day is exactly why a.m. must be treated as the start of a day, not the end of the previous one.
A segment can belong to a single day iff:
Why is that sufficient? Because those are exactly the constraints from the statement:
Now here's the tiny but useful simplification: inside a nondecreasing sequence, equal values appear in one consecutive run. So condition 2 is equivalent to saying:
Every run of equal times has length at most .
That means we do not need a full frequency table. Just track the current streak of equal minutes.
Take the longest valid prefix as the first day, then repeat on the remaining suffix.
Let the current day start at position , and let be the largest index such that is a valid one-day block.
Consider any optimal partition. Its first block cannot end after — by definition of , anything longer is invalid.
Suppose its first block ends earlier, at some . Then we can move records from the front of later blocks into the first block.
So there exists an optimal solution whose first block is exactly the greedy longest valid prefix. Apply the same argument to the suffix. Done.
In plain English: if the next record still fits in the current day, cutting earlier is just self-inflicted pain. If the next record does not fit, then starting a new day is forced.
Maintain for the current day:
last = the last minute value,same = length of the current run of equal times.For each next time :
same = 10, this would be the -th record in the same minute of the same day, so again it must start a new day;That's it. Simple, brutal, correct.
The scan is time and memory.
With , this is hilariously safe.
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
void setIO() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
}
int main() { setIO();
int n;
cin >> n;
string s;
getline(cin, s); // consume endline after n
vector<int> t(n);
for (int i = 0; i < n; ++i) {
getline(cin, s);
int hh = (s[1] - '0') * 10 + (s[2] - '0');
int mm = (s[4] - '0') * 10 + (s[5] - '0');
char ap = s[7]; // 'a' or 'p'
int hour = hh % 12 + (ap == 'p' ? 12 : 0);
t[i] = hour * 60 + mm;
}
int days = 1;
int last = t[0];
int same = 1;
for (int i = 1; i < n; ++i) {
if (t[i] < last || (t[i] == last && same == 10)) {
++days;
last = t[i];
same = 1;
} else {
if (t[i] == last) {
++same;
} else {
last = t[i];
same = 1;
}
}
}
cout << days << '\n';
return 0;
}#include <bits/stdc++.h>
using namespace std;
using ll = long long;
void setIO() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
}
int main() { setIO();
int n;
cin >> n;
string s;
getline(cin, s); // consume endline after n
vector<int> t(n);
for (int i = 0; i < n; ++i) {
getline(cin, s);
int hh = (s[1] - '0') * 10 + (s[2] - '0');
int mm = (s[4] - '0') * 10 + (s[5] - '0');
char ap = s[7]; // 'a' or 'p'
int hour = hh % 12 + (ap == 'p' ? 12 : 0);
t[i] = hour * 60 + mm;
}
int days = 1;
int last = t[0];
int same = 1;
for (int i = 1; i < n; ++i) {
if (t[i] < last || (t[i] == last && same == 10)) {
++days;
last = t[i];
same = 1;
} else {
if (t[i] == last) {
++same;
} else {
last = t[i];
same = 1;
}
}
}
cout << days << '\n';
return 0;
}