题目描述
输入样例1
8
13:00:00 - 18:00:00
00:00:00 - 01:00:05
08:00:00 - 09:00:00
07:10:59 - 08:00:00
01:00:05 - 04:30:00
06:30:00 - 07:10:58
05:30:00 - 06:30:00
18:00:00 - 19:00:00
输出样例1
04:30:00 - 05:30:00
07:10:58 - 07:10:59
09:00:00 - 13:00:00
19:00:00 - 23:59:59
输入样例2
1
13:00:00 - 18:00:00
输出样例2
00:00:00 - 13:00:00
18:00:00 - 23:59:59
思路
区间合并
1.存储结构:
①结构体Time,存储每一个时间端点具体的时分秒
②map,存储每一个时间端点和其转化为以秒为时间的映射
③vector存储用秒表示的一队给定时间区间
2.具体做法
①将存储结构中的数据存好之后,首先对vector数组进行排序,由于vector的元素是pair,使用sort,默认按pair的first由小到大排序
②初始化区间端点为负无穷,即没有区间,这样我们可以更新第一个区间
③判断从第二个开始的区间,如果当前区间的尾端点,比我们先前合并的区间首端点小,说明两个区间没有重合,则将先前的区间保存下来,并将新的区间端点,更新为当前我们判断的区间;否则,区间有重合,合并区间,更新尾端点
AC代码
#include <iostream>
#include <cstdio>
#include <vector>
#include <map>
#include <algorithm>
using namespace std;
const int N = 100010;
typedef struct time
{
int h, m, s;
}Time;
typedef pair<int, int> PII;
vector<PII> segs; //起始时间 终止时间 均以秒为单位
map<int, Time> mp; //对应的以秒为单位的时间 具体时间
Time t1, t2;
//void test()
//{
// cout << "------" << endl;
// for(int i = 0; i < segs.size(); i ++)
// {
// int st = segs[i].first;
// int ed = segs[i].second;
// t1 = mp[st];
// t2 = mp[ed];
// printf("%02d:%02d:%02d - %02d:%02d:%02d\n", t1.h, t1.m, t1.s, t2.h, t2.m, t2.s);
// }
//}
void merge()
{
vector<PII> temp;
int seg_st = -2e9, seg_ed = -2e9;
for(int i = 0; i <segs.size(); i ++)
{
if(seg_ed < segs[i].first) //产生新的区间
{
if(seg_st != -2e9) temp.push_back({seg_st, seg_ed});
seg_st = segs[i].first;
seg_ed = segs[i].second;
}
else seg_ed = max(seg_ed, segs[i].second); //有重合部分,合并区间
}
if(seg_st != -2e9) temp.push_back({seg_st, seg_ed}); //不要忘记最后一个区间
segs = temp;
// //测试区间合并正确性
// test();
int st, ed;
st = segs[0].first;
t1 = mp[st];
if(t1.h || t1.m || t1.s) printf("00:00:00 - %02d:%02d:%02d\n", t1.h, t1.m, t1.s); //判断从00:00:00到给定的最早时间是否有漏掉的时间
for(int i = 1; i < segs.size(); i ++)
{
st = segs[i].first;
ed = segs[i - 1].second;
t2 = mp[st];
t1 = mp[ed];
printf("%02d:%02d:%02d - %02d:%02d:%02d\n", t1.h, t1.m, t1.s, t2.h, t2.m, t2.s);
}
//判断从给定的最晚时间到23:59:59是否有漏掉的时间
ed = segs[segs.size() - 1].second;
t1 = mp[ed];
if(t1.h != 23 || t1.m != 59 || t1.s != 59) printf("%02d:%02d:%02d - 23:59:59\n", t1.h, t1.m, t1.s);
}
int main()
{
int n;
scanf("%d", &n);
for(int i = 0; i < n; i ++)
{
int h1, m1, s1, h2, m2, s2;
scanf("%d:%d:%d - %d:%d:%d", &h1, &m1, &s1, &h2, &m2, &s2);
t1 = {h1, m1, s1}; //存储当前区间的开始时间
t2 = {h2, m2, s2}; //存储当前区间的结束时间
int time1 = h1 * 3600 + m1 * 60 + s1; //开始时间转化为以秒为单位
int time2 = h2 * 3600 + m2 * 60 + s2; //结束时间转化为以秒为单位
mp[time1] = t1; //映射关系
mp[time2] = t2;
segs.push_back({time1, time2});
}
sort(segs.begin(), segs.end());
// //测试排序正确性
// test();
merge();
return 0;
}
欢迎大家批评指正!!!