问题描述
如果你认为参加一个编程比赛让你感到有压力,那么请你想象你是一个空中交通管制员。因为人命关天,所以一个空中交通管制员必须在时刻变化的环境中专注于任务,解决不可预知的事件。
让我们将目光转向飞机的着陆流程。飞机进入目的地飞航情报区之后,就会报告自己的位置、方向和速度,然后管制员就需要制定计划让所有飞机按指令安全着陆。一般来说,连续的两次着陆之间间隔时间越长,就越安全。因为这些额外的时间能够让工程师有机会对天气变化以及其他突发事件作出反应。
幸运的是,有一部分计划的制定可以自动化——这就是你来这里的原因。你会得到有关飞机着陆的脚本。每一个飞机都有一个安全着陆时间窗。你算出的指令必须要符合每个飞机的时间窗。另外,飞机的着陆时间点要尽量均匀,使得连续两次着陆的最小间隔尽量大。例如,如果三架飞机分别着陆于10:00am、10:05am、10:15am,那么最小间隔是五分钟,在头两架飞机之间。所有间隔不一定一样,但是最小的间隔要尽量大。
输入格式
多组数据。每个数据第一行为一个整数n,为飞机架数。接下来n行,每行两个整数a[i],b[i]表示这架飞机只能在闭区间[a[i],b[i]]间降落。a[i]和b[i]的单位是分钟。输入的最后一行是一个零。
输出格式
对于每组数据,先输出第几组,然后输出最小间隔,单位为分和秒,舍入到最近的整数。格式参见样例。
样例输入
3
0 10
5 15
10 15
2
0 10
10 20
0
样例输出
Case 1: 7:30
Case 2: 20:00
数据规模和约定
20% n<=5
100% 2<=n<=8, 0<=a[i], b[i]<=1440, 数据组数不大于20.
思路:最小值最大问题,二分. 这个题不知道怎么对数据排序,又看到最多就有8架飞机,所以我们可以求全排列,对每种排列二分求值.
复杂度O(n!*log2max(b[i])),最大不过1e6.
代码:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<stack>
#include<cstring>
#include<string>
#include<vector>
#include<cmath>
#include<map>
#define mem(a,b) memset(a,b,sizeof(a))
#define mod 1000000007
using namespace std;
typedef long long ll;
const int maxn = 1e5+5;
const double esp = 1e-7;
const int ff = 0x3f3f3f3f;
map<int,int>::iterator it;
int n,num[15];
double a[15],b[15];
bool judge(double x)
{
double l = a[num[0]];
for(int i = 1;i< n;i++)
{
if(l+x> b[num[i]])
return 0;
l+= x;
l = max(a[num[i]],l);
}
return 1;
}
int main()
{
int cnt = 0;
while(~scanf("%d",&n)&&n)
{
for(int i = 0;i< n;i++)
{
cin>>a[i]>>b[i];
num[i] = i;
}
double ans = 0;
do
{
double l = 0,r = 10000;
while(r-l> esp)
{
double mid = (l+r)/2;
if(judge(mid))
l = mid;
else
r = mid;
}
ans = max(ans,r);
}while(next_permutation(num,num+n));
ans*= 60;
printf("Case %d: %d:%02d\n",++cnt,(int)ans/60,(int)(fmod(ans,60)+0.5));//记得四舍五入+0.5
}
return 0;
}