題目鏈接:
試題編號: 201809-2
試題名稱: 買菜
題意
給出兩個人的N次送貨上車的時間段,求重合的時間段的總長度。
分析
兩個人的開始時間和結束時間分別爲s1,s2,e1,e2.將每個人的時間段按照開始時間遞增排序,分別用i,j指針指向兩個人的第幾個時間段。類似於歸併排序,將沒有交集的時間段跳過,即當一個人的結束時間小於等於另一個人的開始時間不可能有交集,除了下面的兩種情況都是交集。
因此只需要判斷有交集的時間段即可。交集中連續時間段的開始時間s等於max(s1,s2),結束時間e等於min(e1,e2). 交集時間爲 e-s。
- e1小則i++;
- e2小則j++;
- 相等則i++,j++.
代碼實現
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
using namespace std;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
typedef struct Node{
int s, e;
Node(){ };
Node(int ts, int te){
s = ts;
e = te;
}
}Node;
bool cmp(Node n1, Node n2) {
return n1.s < n2.s;
}
Node arr1[2010], arr2[2010];
int main(int argc, char** argv) {
int n, s, e;
scanf("%d", &n);
for (int i = 0; i < n; i++) {
scanf("%d%d", &arr1[i].s, &arr1[i].e);
}
for (int i = 0; i < n; i++) {
scanf("%d%d", &arr2[i].s, &arr2[i].e);
}
sort(arr1, arr1 + n, cmp);
sort(arr2, arr2 + n, cmp);
int i = 0, j = 0, sum = 0;
while (i < n && j < n) {
if (arr1[i].e <= arr2[j].s)
i++;
else if (arr2[j].e <= arr1[i].s)
j++;
else { // 交集,前取大後取小,後小則後移一位
s = max(arr1[i].s, arr2[j].s);
e = min(arr1[i].e, arr2[j].e);
sum += e - s;
if (arr1[i].e < arr2[j].e)
i++;
else if (arr1[i].e > arr2[j].e)
j++;
else {
i++;
j++;
}
}
}
printf("%d", sum);
return 0;
}