蓝桥 A Careful Approach 枚举+贪心+二分

传送门

思路:

一看到这个题目应该首先想到二分吧,最小问题最大化,最大问题最小化我们就考虑是否具有单调性是否能二分.

想完二分之后我们需要考虑如何check, 仅仅是简单的排序 check是不可行的,因为我们不太确定能够按哪个端点来排序一定是正确的.

进而观察到题目中说n <= 8。那么我们是否可以暴力枚举出每个飞机降落的顺序,然后在按照贪心的思想,对当前二分的答案,让每个飞机在能降落的情况下尽可能早的降,然后维护最优解即可.

 

这里的到达顺序可以用dfs来写,我是用next_permutation 来直接搞得全排列.

 


#include<bits/stdc++.h>
#define eps (1e-6)
using namespace std;
const int maxn = 10;
int num[maxn],pos[maxn];
struct node{
    int a,b;
}s[maxn];
int n;
double ans ;
bool check(double len)
{
    double x = s[pos[1]].a;
    for(int i = 2;i <= n;++i)
    {
        x += len;
        if(x > s[pos[i]].b)
            return 0;
        if(x < s[pos[i]].a)
            x = s[pos[i]].a;
    }
    return 1;
}
int main()
{
    int ca = 1;
    while(~scanf("%d",&n))
    {
        if(n == 0) break;
        for(int i = 1;i <= n;++i)
        {
            num[i] = i;
            scanf("%d %d",&s[i].a,&s[i].b);
            //s[i].a *= 60,s[i].b *= 60;
        }
        ans = 0;
        do{
            for(int i = 1;i <= n;++i)
            {
                pos[num[i]] = i;
            }
            /*for(int i = 1;i <= n;++i)
                printf("%d",num[i]);
            puts("");*/
            double l = 0,r = 1440,mid;
            while(r - l > eps)
            {
                mid = (l + r) / 2;
                if(check(mid))
                    l = mid;
                else
                    r = mid;
            }
            ans = max(ans,r);
        }while(next_permutation(num + 1, num + 1 + n));
        ans *= 60;
        printf("Case %d: %d:%02d\n",ca++,(int)ans / 60,int(fmod(ans,60) + 0.5));
    }
    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章