标签:
瓦特尔,阿隆索,汉密尔顿在F1上海站进行比赛,每人必须进维修站更换轮胎一次(谁出的无聊规定?!),而且只能进维修站一次。
阿隆索在20秒进站换胎,一直到90秒出站。瓦特尔在60秒开始进站,在 130秒结束。汉密尔顿在160秒开始220秒结束。期间最长的至少有一个车手在维修区的连续时间为110秒(从20秒到130秒),而最长的无人在维修区的连续时间(从有人进维修站开始一直到出维修站)为30秒(从130秒到160秒)。
假设现在又进行了一场有N个车手的比赛,你的任务是编一个程序,读入一个有N个车手(1 <= N <= 5000)进N次站的工作时间列表,计算以下两点(均以秒为单位):
最长至少有一人在维修站内的时间段。
最长的无人在维修站的时间段。(从有人进站开始算起)
第1行:一个整数N。
第2至第N+1行:每行两个小于1000000的非负整数,表示一个车手的进站时刻与出站时刻。
一行,两个整数,即题目所要求的两个答案。
3
200 900
600 1300
1600 2200
1100 300
最直觉的想法是把可以合并的连续有车的时间合并起来,算作一个时间段,构建一个只有不重合且不连续的若干个区间,然后就可以很容易的得到答案了.
构建的时候,可以考虑首先把这些区间(按照开始时间的先后)排序,方便逻辑处理.
在合并的过程中,对两个区间进行分类讨论. 有交叉(相等) 包含 或者根本无交集.
#include <iostream> #include <stdlib.h> using namespace std; struct carPeriod { int start; int end; }; carPeriod cars[5001]; carPeriod newcars[5001]; int cmp_carperiod_1(const void* _a, const void* _b){ carPeriod* a = (carPeriod*) _a; carPeriod* b = (carPeriod*) _b; return (*a).start - (*b).start; } int main(int argc, char const *argv[]) { int N;cin>>N; for (int i = 0; i < N; ++i) cin>>cars[i].start>>cars[i].end; int maxIN=0, maxOUT=0; qsort(cars, N, sizeof(carPeriod),cmp_carperiod_1);//根据进入的时间排序 int newN = 0;//新时间段的个数 newcars[newN].start = cars[0].start; //第一个时间段 newcars[newN].end = cars[0].end; //目标: 把所有的有交集的时间段组合起来 for (int i = 1; i < N; ++i) { if(cars[i].start <= newcars[newN].end and cars[i].end >= newcars[newN].end){//交叉关系 newcars[newN].end = cars[i].end;//接上 } else if(cars[i].start >newcars[newN].start and cars[i].end<newcars[newN].end) continue;//包含关系 不进行任何操作 else{ newN++;//无交集 建立新的片段 newcars[newN].start = cars[i].start; newcars[newN].end = cars[i].end; } } // cout<<"------"<<endl; // for (int i = 0; i <= newN; ++i) // cout<<newcars[i].start<<" "<<newcars[i].end<<endl; // cout<<"------"<<endl; //maxIN for (int i = 0; i <= newN; ++i) { int period = (newcars[i].end - newcars[i].start); if( period > maxIN ) maxIN = period; } //maxOUT for (int i = 1; i <= newN; ++i) { int interval = newcars[i].start - newcars[i-1].end; if( interval > maxOUT ) maxOUT = interval; } cout<<maxIN<<" "<<maxOUT<<endl; return 0; } /* 4 2 5 10 101 10 101 80 102 */
【算法学习笔记】37.区间合并问题 SJTU OJ 1262 Milking Cow
标签:
原文地址:http://www.cnblogs.com/yuchenlin/p/4466852.html