Codeforces Educational Codeforces Round 27 - C - Two TVs

C. Two TVs
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

Polycarp is a great fan of television.

He wrote down all the TV programs he is interested in for today. His list contains n shows, i-th of them starts at moment li and ends at moment ri.

Polycarp owns two TVs. He can watch two different shows simultaneously with two TVs but he can only watch one show at any given moment on a single TV. If one show ends at the same moment some other show starts then you can't watch them on a single TV.

Polycarp wants to check out all n shows. Are two TVs enough to do so?

Input

The first line contains one integer n (1 ≤ n ≤ 2·105) — the number of shows.

Each of the next n lines contains two integers li and ri (0 ≤ li < ri ≤ 109) — starting and ending time of i-th show.

Output

If Polycarp is able to check out all the shows using only two TVs then print "YES" (without quotes). Otherwise, print "NO" (without quotes).

Examples
input
3
1 2
2 3
4 5
output
YES
input
4
1 2
2 3
2 3
1 2
output
NO


题意:有两台电视,有n个节目,每个节目有各自的播放时间,判断能否用两台电视将所有节目都看完,两个节目若一节目结束时间和另一节目开始时间相同,它们需要在两个电视观看。


看了别人的题解,感觉自己的想法实在是不行,直接对两个电视工作情况进行模拟更好一些。

思路:就是找会不会有哪一个时间有三个或三个以上的节目在播放。因为三个就不行了所以我们只要找三个就行了。对每一个节目都找覆盖在其内的节目,贪心,先对所有节目进行排序,开始时间由小到大,若开始时间相同则结束时间由小到大。从前到后遍历,只用找在该节目之前播出的最迟结束的两个节目(用优先队列可以得到两个之前播出的最大的结束时间)和在该节目播出后的最早播放的两个节目(就是在该节目播放后的两个节目,以及排好序的),看其重合部分(要仔细考虑重合的部分到底在哪)。


写的时候很多问题没有注意到,昨天改了又改,本来以为终于对了结果今天早上起来就被hack了尴尬

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<queue>
#include<functional>
using namespace std;
#define LL long long
const LL maxn = 2*1e5;
struct node
{
    LL st,ed;
}a[maxn+5];
LL n;
bool cmp(node a,node b)
{
    if(a.st==b.st)
        return a.ed<b.ed;
    return a.st<b.st;
}
int main()
{
    while(scanf("%lld",&n)!=EOF)
    {
        memset(a,0,sizeof a);
        for(int i=0;i<n;i++)
            scanf("%lld%lld",&a[i].st,&a[i].ed);
        sort(a,a+n,cmp);
        int flag = 0;
        priority_queue<LL,vector<LL>,less<LL> >q;
        while(!q.empty()) q.pop();
        q.push(a[0].ed),q.push(a[1].ed);
        for(int i=2;i<n;i++)
        {
            LL t = q.top(),cnt1 = 0,cnt = 0;
            q.pop();
            if(t>=a[i].st) cnt1++;//|_____|_____| ,其中第一个|和最后一个|代表第i个节目的开始和结束时间,中间的|代表之前播出的最迟的结束时间,画的是满足条件的情况,其中重复的部分是第1个|到第二个|之间。
            if(q.top()>=a[i].st) cnt1++;//|___|_|_____|,这里也是画满足条件的情况,其中重复的部分也是第1个|到第二个|之间。
            if(i+1<n&&a[i+1].st<=a[i].ed) cnt++;//
            if(i+2<n&&a[i+2].st<=a[i].ed&&a[i+2].st<=a[i+1].ed) cnt++;//要考虑到上一个结束时间较早的情况,如:|_!___!_#__#_|,其中!代表下面第一个节目,#代表第二个
            if((cnt&&a[i+1].st<=t)||cnt>=2||cnt1>=2)//后面的和前面的重合,前面的和前面的重合,后面的和后面的重合
            {
                flag = 1;
                break;
            }
            q.push(t);
            q.push(a[i].ed);
        }
        if(flag)
            printf("NO\n");
        else
            printf("YES\n");
    }
    return 0;
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值