题目大意:
有N个农民,每个农民在一段时间内工作--挤牛奶,每个农民的工作时间可能有重叠也可能没有重叠。则我们可以知道会存在一段时间内连续有人工作,同时也可能会存在一段时间内没有一个人在工作。
比如,有三个农民,第一个农民的工作时间是第300到第1000秒,第二个农民的工作时间是第700到第1200秒,第三个农民的工作时间是第1500到2100秒。则最长的连续有人工作的时间是900秒(从第300到第1200秒),最长的无人工作时间是300秒(从第1200到第1500秒)。
输入格式
line 1:N(表示N个农民,1<=N<=5000)
line 2-N+1:每行两个数(小于1000000的非负整数),分别表示工作的开始时间和结束时间
输出格式
一行两个整数,分别为最长连续有人工作时间和最长无人工作时间。
样例输入
3
300 1000
700 1200
1500 2100
样例输出
900 300
题解
显然,有开始时间必定有结束时间。同时,如果从最开始的起始时间到某一个结束时间点A为止,其中包含的开始时间点大于其中包含的结束时间点(包括端点),那么一定有某个(也有可能是某些)其中包含的开始时间点对应的结束时间点在这个结束时间点A之后,即连续时间段可以向后延伸。
同时知道两个最长连续时间段之间一定是没有人工作的空白时间段,否则两个连续时间段不是最长的。所以空白时间段的长度即为:最长连续时间段的截止结束时间点到紧接的下一个开始时间点的间隔。
| | | | | |
开始1 开始2 结束1 结束2 开始3 结束3
------------------ 时间段1
-------------- 时间段2
------
时间段3
*****空时间段
根据以上想法提出如下算法:
将开始时间点按升序排序,结束时间点也按升序排序。依此遍历每个结束时间点,并求出对应范围内(从起始到这个结束时间点截止)的开始时间点个数,如果等于其内包含的结束时间点个数,则记录该连续时间段长度last,同时记录此结束时间点到紧接的下一个开始时间点的间隔长度empty。
取最大的last和empty,即为所求。
代码:
#include<stdio.h>
int main()
{ long int tables[5010],tablee[5010],temp,last[5000],
empty[5000],a=0,b=0;
int N,i,counts=0,j,k,s;
scanf("%d",&N);
for(i=0;i<N;i++)
{
scanf("%ld",&tables[i]);
scanf("%ld",&tablee[i]);
}
for(i=0;i<N;i++)
for(j=0;j<N-i-1;j++)
{
if(tablee[j]>tablee[j+1])
{
temp=tablee[j];
tablee[j]=tablee[j+1];
tablee[j+1]=temp;
}
}
for(i=0;i<N;i++)
for(j=0;j<N-i-1;j++)
{
if(tables[j]>tables[j+1])
{
temp=tables[j];
tables[j]=tables[j+1];
tables[j+1]=temp;
}
}
s=0;
for(i=0;i<N;i++)
{
counts=0;
for(k=0;k<N;k++)
{
if(tables[k]>=tables[0]&&tables[k]<=tablee[i])
counts++;
}
if(counts==i+1)
{
last[j]=tablee[i]-tables[s];
s=i+1;
if(s<N)
empty[j]=tables[s]-tablee[i];
j++;
}
}
for(i=0;i<j;i++)
{
if(a<last[i])
a=last[i];
}
for(i=0;i<j-1;i++)
{
if(b<empty[i])
b=empty[i];
}
printf("%ld %ld\n",a,b);
return 0;
}