2008 北京区域赛 Priest John's Busiest Day

/*

题目:
    有n对新人,他们的婚礼时间分别为[s,t],他们的习俗是需要牧师能够对新人
    进行祝福,要求牧师的祝福时间超过他们婚礼的持续时间的一半。问只有一个
    牧师的话能不能成功主持所有这样婚礼

分析:
    贪心,可以先求出所有新人所需要祝福的时间,由于改时间超过婚礼的一半,
    所以在[s,t]的中间时刻一定是要祝福新人,比如[1,5]时,2,3,4均要祝福;
    [1,4]时,2,3需要祝福,所以可以定义
    ms:必须在祝福的最晚起始时间,
    me:必须在祝福的最早终止时间。
    我们通过对ms进行排序,若相等则按me进行排序,再判断是否符合即可

*/
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

const int X = 100005;

int n;

struct node
{
    int s,e;
    int ms,me;
    int mid;
    friend bool operator < (node a,node b)
    {
        return a.ms<b.ms||(a.ms==b.ms&&a.me<b.me);
    }
}p[X];

int main()
{
    freopen("sum.in","r",stdin);
    freopen("sum.out","w",stdout);
    while(scanf("%d",&n),n)
    {
        for(int i=0;i<n;i++)
        {
            scanf("%d%d",&p[i].s,&p[i].e);
            p[i].ms = (p[i].s+p[i].e-1)>>1;
            p[i].me = p[i].ms+1;
            if(!((p[i].s+p[i].e)&1))
                p[i].me++;
            p[i].mid = (p[i].e-p[i].s+2)>>1;
        }
        sort(p,p+n);
        bool flag = false;
        int temp = p[0].me;
        for(int i=1;i<n;i++)    //主要算法
        {
            if(temp<=p[i].s)    //还没或者恰好到该位置的起始时间
            {
                temp = p[i].me;
                continue;
            }
            temp += p[i].mid;
            if(temp>p[i].e)
            {
                flag = true;
                break;
            }
        }
        flag?printf("NO\n"):printf("YES\n");
    }

    return 0;
}
原文地址:https://www.cnblogs.com/yejinru/p/2547788.html