题目链接:https://www.luogu.com.cn/problem/P1204
知识点:贪心
即若当前时间段不连续,则取当前最大的连续时间段与最大空闲时间段。
思路:
1.首先将所有农夫的工作时间,以起始时间最早进行排序
2.寻找最长连续时间,最长空闲时间
flag1=当前连续时间起始点; flag2=当前连续时间结束点;
如果当前农夫的工作起始时间 > flag2,即有空闲时间,那么:
①计算更新此前的最长连续时间
sum1 = max ( sum1, flag2 - flag1);
②计算更新此时的最长空闲时间
sum0 = max ( sum0, 当前农夫的工作起始时间 - flag2 );
③更新当前连续时间起始点,当前连续时间结束点
flag1 = 当前农夫工作起始时间;
flag2 = 当前农夫工作结束时间;
如果当前农夫的工作起始时间 <= flag2,即当前连续时间段增长,那么
①更新当前连续时间结束点
flag2 = 当前农夫工作结束时间
3.由于最后一次连续时间段没有进入循环计算,故最后再更新一次最长连续时间
sum1 = ( sum1, flag2 - flag1 );
完整代码如下:
#include <iostream>
#include <algorithm>
using namespace std;
struct Time{
long long begin;
long long end;
}p[ 5005 ];
int n;
long long sum1, sum0;
int cmp ( Time a, Time b )
{
return a.begin < b.begin;
}
void print()
{
puts( "" );
for ( int i = 0; i < n; ++ i )
{
printf ( "%lld %lld\n", p[ i ].begin, p[ i ].end );
}
puts( "" );
}
void solve ( )
{
sort ( p, p + n, cmp );
//print();
int flag1, flag2;
flag1 = p[ 0 ].begin; // 最早连续时间
flag2 = p[ 0 ].end; // 最迟连续时间
int flag = p[ 0 ].begin;
for ( int i = 1; i < n; ++ i )
{
if ( p[ i ].begin > flag2 ) // 有空闲时间段
{
// 更新最长空闲时间
sum0 = sum0 > ( p[ i ].begin - flag2 ) ? sum0 : ( p[ i ].begin - flag2 );
// 更新最长连续时间
sum1 = sum1 > ( flag2 - flag1 ) ? sum1 : ( flag2 - flag1 );
flag1 = p[ i ].begin; // 标记新的连续时间段起始点
flag2 = p[ i ].end; // 标记新的连续时间段结束点
}
else // 更新连续时间段结束点
{
flag2 = flag2 > p[ i ].end ? flag2 : p[ i ].end;
}
}
// 由于最后一次连续时间没有进入循环计算,故再更新一次
sum1 = sum1 > ( flag2 - flag1 ) ? sum1 : ( flag2 - flag1 );
printf ( "%lld %lld\n", sum1, sum0 );
}
int main ( )
{
scanf ( "%d", &n );
for ( int i = 0; i < n; ++ i )
{
scanf( "%lld %lld", &p[ i ].begin, &p[ i ].end );
}
solve();
system( "pause" );
return 0;
}
学海无涯