前言
看到很多同学好像是关注了我,大家要学习一下代码呢,不能直接copy哦。
题目
思路
其实这题我是抄的hhh,今天早上看了一下代码,觉得原来别人写的太冗长了,没有必要,所以按照自己的思路写了一下。
总体的思路是利用给出的飞机起飞的时候是按照升序给出的,所以我们不需要额外的对时间处理工作,只用线性查找即可。关键在于如何判断今天的最后一架飞机与明天的第一架飞机之间的时间跨度。
刚开始想到了约瑟夫环( 程设书的P139 ),但是这个题只有一个答案,也就意味着我们只用一次线性遍历即可,不需要额外的技巧连接成环。
当我们遍历到最后一架飞机的时候,需要特殊判断一下它与第一架飞机时间之间的关系就好了,而这架飞机的+T+1后的时间很有可能跨越了00:00这个特殊的时间段,因此我们还需要判断,其实关系理顺了就很简单。
AC代码
#include <bits/stdc++.h>
using namespace std;
int main() {
int n, T;
cin >> n >> T;
int plane[n + 1][2]; //n+1防止越界
for (int i = 1; i <= n; ++i) {
cin >> plane[i][0] >> plane[i][1];
}
/*由于会存在一种情况是该天的最后一次飞机与明天
的第一架飞机起飞时间的比较问题,因此我们需要在最后一架飞机特判一下*/
int res = INT_MAX, temp1, temp2;
for (int i = 1; i <= n; ++i) {
if (i != n) {
temp1 = plane[i][0] * 60 + plane[i][1];
temp2 = plane[i + 1][0] * 60 + plane[i + 1][1];
if (temp2 - temp1 >= 2 * T + 2) {
res = min(temp1 + T + 1, res);
}
} else { //特判
temp1 = plane[n][0] * 60 + plane[n][1];
temp2 = plane[1][0] * 60 + plane[1][1];
temp1 = temp1 + T + 1;
if (temp1 >= 24 * 60) {
//第一种情况是+T+1后来到了第二天
temp1 -= 24 * 60; //首先返回去
if (temp2 - temp1 > T) {
res = min(temp1, res);
break;
}
} else {
//第二种情况是+T+1后还在今天
int delt1 = 24 * 60 - temp1;
//delt1为今天距离00:00的时间 temp2视为第二天距离00:00的时间
if (delt1 + temp2 > T) {
res = min(temp1, res);
break;
}
}
}
}
cout << res / 60 << " " << res - res / 60 * 60;
/*取min的原因在于由于数组是顺序遍历的,所以我们无法在一开始就确定
昨天的最后一架飞机是否能起飞,这种情况是最早的一次*/
}