算法提高 A Careful Approach

问题描述
  如果你认为参加一个编程比赛让你感到有压力,那么请你想象你是一个空中交通管制员。因为人命关天,所以一个空中交通管制员必须在时刻变化的环境中专注于任务,解决不可预知的事件。
  让我们将目光转向飞机的着陆流程。飞机进入目的地飞航情报区之后,就会报告自己的位置、方向和速度,然后管制员就需要制定计划让所有飞机按指令安全着陆。一般来说,连续的两次着陆之间间隔时间越长,就越安全。因为这些额外的时间能够让工程师有机会对天气变化以及其他突发事件作出反应。
  幸运的是,有一部分计划的制定可以自动化——这就是你来这里的原因。你会得到有关飞机着陆的脚本。每一个飞机都有一个安全着陆时间窗。你算出的指令必须要符合每个飞机的时间窗。另外,飞机的着陆时间点要尽量均匀,使得连续两次着陆的最小间隔尽量大。例如,如果三架飞机分别着陆于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.

蓝桥再不变,估计就会变成下一个飞信,题目都错,还在这些出培训课,只知道赚钱了。数据写着<1440,可他数据里面出现了  >1440的情况,太。。。

#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
#define bug(x) printf("%d***\n",x)
#define ls(x) (x<<1)
#define rs(x) (x<<1|1)
using namespace std;
typedef long long ll;
/*
long long类型同一用 %lld 
排序的情况是不对的
例如  1                         1000
         2       50    
                          900	      1200
如果1号先飞的话,				  		
*/ 
const double eps=1e-3;//精度 ,我们如果变成秒的话,只能精确到秒,可是这道题,我们要精确到小数点,再去保留 
struct node{
	double l,r;
	node(){	}
	node(double _l,double _r){
		l=_l,r=_r;
	}
}p[10];

int n;
int tim[20]; 
int check(double x){
	 for(int i=1;i<=n;i++)
	 	tim[i]=i;
	int flag=0;
	do{
		int bf=0;
		double st=p[tim[1]].l;
		for(int i=2;i<=n;i++){
			st+=x;
			if(st-p[tim[i]].r>eps){
				bf=1;
				break;
			}	
			st=max(st,p[tim[i]].l);
		}
		/*
		for(int j=1;j<=n;j++){
			printf("x:%f j:%d %d\n",x,j,tim[j]);
		}
		*/
		if(!bf){
			flag=1;
			break;
		}
	}while(next_permutation(tim+1,tim+n+1));
	return flag==1?1:0;
}

int main(){
//	freopen("123.txt","w",stdout);
	int T=1;
	while(scanf("%d",&n)==1&&n){
		double mx=0; 
		for(int i=1;i<=n;i++){
			double a,b;
			scanf("%lf %lf",&a,&b);
			mx=max(mx,a),mx=max(mx,b);
			p[i]=(node){a,b};
		}
		double l=0,r=mx,mid;
		double ans;
		while(r-l>eps){
			mid=(l+r)/2.0;
			if(check(mid)){
				ans=mid;
				l=mid;
			}
			else
				r=mid;
		}
		ans+=eps;
		//printf("ans:%.3f\n",ans);
		int h=(int)(ans),m=(int)((ans-h*1.0)*60.0+0.5);
		printf("Case %d: %d:%02d\n",T++,h,m);
	}
	return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值