问题描述
小H和小W来到了一条街上,两人分开买菜,他们买菜的过程可以描述为,去店里买一些菜然后去旁边的一个广场把菜装上车,两人都要买n种菜,所以也都要装n次车。具体的,对于小H来说有n个不相交的时间段[a
1,b
1],[a
2,b
2]...[a
n,b
n]在装车,对于小W来说有n个不相交的时间段[c
1,d
1],[c
2,d
2]...[c
n,d
n]在装车。其中,一个时间段[s, t]表示的是从时刻s到时刻t这段时间,时长为t-s。
由于他们是好朋友,他们都在广场上装车的时候会聊天,他们想知道他们可以聊多长时间。
由于他们是好朋友,他们都在广场上装车的时候会聊天,他们想知道他们可以聊多长时间。
输入格式
输入的第一行包含一个正整数n,表示时间段的数量。
接下来n行每行两个数a i,b i,描述小H的各个装车的时间段。
接下来n行每行两个数c i,d i,描述小W的各个装车的时间段。
接下来n行每行两个数a i,b i,描述小H的各个装车的时间段。
接下来n行每行两个数c i,d i,描述小W的各个装车的时间段。
输出格式
输出一行,一个正整数,表示两人可以聊多长时间。
样例输入
4
1 3
5 6
9 13
14 15
2 4
5 7
10 11
13 14
1 3
5 6
9 13
14 15
2 4
5 7
10 11
13 14
样例输出
3
数据规模和约定
对于所有的评测用例,1 ≤ n ≤ 2000, a
i < b
i < a
i+1,c
i < d
i < c
i+1,对于所有的i(1 ≤ i ≤ n)有,1 ≤ a
i, b
i, c
i, d
i ≤ 1000000。
思路
1.把两人装车的时间放在一个坐标轴上,就能发现其实可以通过一个数组来建立这个坐标轴。当有人在装车的时候,就把该时间段的数组值+1,那么最终当该部分值为2,就代表这个时间段两人都在。
2.
要以时间段为数组,而不能以时间点。我开始就写成了以时间点,测试了样例也是正确的(但仔细分析不应该正确,很玄学)。如果是以某个时间点是否有人的话,那么是否可以以最后整理为2的时间点次数除以2呢?我当时是这么想更简单解决的,但是显然不可以。就像题中给出的例子,当A:9 13、14 15,B:13 14时,其实是没有交集的,但是两人都在时间点13、14时出现一次,但是A在13-14这个时间段恰好都不在。
3.还有一个就是由于题目给出的“对于所有的i(1 ≤ i ≤ n)有,1 ≤ a
i, b
i, c
i, d
i ≤ 1000000”,当把数组大小设置到100000时,由于数组太大,直接就无法运行了。我当时还想着要不该数据类型用vector,这样可以动态加入,就不用预设一个这么大空间的数组。但我百度了一下,发现解决这个问题最好的方法就是,在main函数之前定义数组,果然有效。看到一个大佬的解释是,
“数组定义在函数中时,占用的内存来自栈空间,栈空间是在进程创建时初始化的,有固定的大小,一般为几十KB,所以太大的数组会耗光栈空间。而全局变量占用的堆空间,堆空间中的内存是按需分配,可以很大。”
题解
#include<iostream> using namespace std; const int maxn=1000000; int numbers[maxn]; int main(){ int n;//表示时间段的数量 scanf("%d",&n); int maxb=0; int time=0; int doublen=2*n; for(int i=0;i<maxn;i++){ numbers[i]=0; } while(doublen--){ int a,b; scanf("%d %d",&a,&b); if(b>=maxb){ maxb=b; } for(int i=a;i<b;i++){ numbers[i-1]++; } } for(int i=0;i<maxb;i++){ if(numbers[i]==2){ time++; } } printf("%d",time); return 0; }