zoukankan      html  css  js  c++  java
  • <cf>Schedule

    Schedule
    time limit per test
    2 seconds
    memory limit per test
    256 megabytes
    input
    standard input
    output
    standard output

    At the beginning of the new semester there is new schedule in the Berland State University. According to this schedule, n groups have lessons at the room 31. For each group the starting time of the lesson and the finishing time of the lesson are known. It has turned out that it is impossible to hold all lessons, because for some groups periods of their lessons intersect. If at some moment of time one groups finishes it's lesson, and the other group starts the lesson, their lessons don't intersect.

    The dean wants to cancel the lesson in one group so that no two time periods of lessons of the remaining groups intersect. You are to find all ways to do that.

    Input

    The first line contains integer n (1 ≤ n ≤ 5000) — amount of groups, which have lessons in the room 31. Then n lines follow, each of them contains two integers li ri (1 ≤ li < ri ≤ 106) — starting and finishing times of lesson of the i-th group. It is possible that initially no two lessons intersect (see sample 1).

    Output

    Output integer k — amount of ways to cancel the lesson in exactly one group so that no two time periods of lessons of the remaining groups intersect. In the second line output k numbers — indexes of groups, where it is possible to cancel the lesson. Groups are numbered starting from 1 in the order that they were given in the input. Output the numbers in increasing order.

    Sample test(s)
    input
    3
    3 10
    20 30
    1 3
    
    output
    3
    1 2 3 
    input
    4
    3 10
    20 30
    1 3
    1 39
    
    output
    1
    4 
    input
    3
    1 5
    2 6
    3 7
    
    output
    0
    
    
    AC Code #1:
    //Memory: 1500 KB		Time: 50 MS
    //Language: GNU C++ 4.6		Result: Accepted
    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    using namespace std;
    
    struct Group
    {
        int s,e,idx;//"s" for start,"e" for end,"idx" for index 
    }a[5001];
    
    int pos[5001],k=0;//pos 记录被舍弃的课程的下标
    int n,i,j;
    bool OK=1;
    
    bool cmp(Group x, Group y)
    {
        if(x.e!=y.e) return x.e<y.e;//按结束时间从小到大排序
        else if(x.s!=y.s) return x.s<y.s;
        else return x.idx<y.idx;
    }
    
    //此函数用于判断去掉a[i]后余下课程是否有时间冲突,是则返回false  
    bool check(int i)
    {
        for(int j=1;j<i-1;j++)
        {
            if(a[j].e>a[j+1].s)
            {
                return 0;
            }
        }
        if(i>1 && i<n && a[i-1].e>a[i+1].s)
        {
            return 0;
        }
        for(int j=i+1;j<n;j++)
        {
            if(a[j].e>a[j+1].s)
            {
                return 0;
            }
        }
        return 1;
    }
    
    int main()
    {
        scanf("%d",&n);
        for(i=1;i<=n;i++)
        {
            scanf("%d%d",&a[i].s,&a[i].e);
            a[i].idx=i;
        }
        sort(a+1,a+n+1,cmp);
        for(i=1;i<n;i++)
        {
            if(a[i].e>a[i+1].s)
            {
                if(!k)
                {
                    bool m=check(i);
                    bool n=check(i+1);
                    if(m && !n) pos[k++]=a[i].idx;
                    else if(!m && n)
                    {
                        pos[k++]=a[i+1].idx;
                        i++;
                    }
                    else if(m && n)
                    {
                        pos[k++]=a[i].idx;
                        pos[k++]=a[i+1].idx;
                        i++;
                    }
                    else
                    {
                        OK=0;
                        break;
                    }
                }
                else
                {
                    OK=0;
                    break;
                }
            }
        }
        if(!OK) puts("0");
        //ok==1但k==0
        else if(!k)
        {
            printf("%d\n",n);
            for(i=1;i<n;i++)
                printf("%d ",i);
            printf("%d\n",i);
        }
        //ok==1 and k>0
        else
        {
            sort(pos,pos+k);
            printf("%d\n",k);
            for(i=0;i<k-1;i++)
                printf("%d ",pos[i]);
            printf("%d\n",pos[i]);
        }
        return 0;
    }
    


    还有一个复杂一点的方法:
    AC Code #2:
    //Memory: 1500 KB		Time: 50 MS
    //Language: GNU C++ 4.6		Result: Accepted
    
    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    using namespace std;
    
    struct Group
    {
        int s,e,idx;
    }a[5001];
    
    int pos[5001],k=0;
    int n,i,j;
    bool OK=1;
    
    bool cmp(Group x, Group y)
    {
        if(x.e!=y.e) return x.e<y.e;//按结束时间从小到大排序
        else if(x.s!=y.s) return x.s<y.s;
        else return x.idx<y.idx;
    }
    
    int check(int i)
    {
        int j=i+1;
        while(a[i].e>a[j].s && j<=n)
        {
            j++;
        }
        return j;
    }
    
    int main()
    {
        scanf("%d",&n);
        for(i=1;i<=n;i++)
        {
            scanf("%d%d",&a[i].s,&a[i].e);
            a[i].idx=i;
        }
        sort(a+1,a+n+1,cmp);
        for(i=1;i<n;i++)
        {
            j=check(i);
            //a[i]的结束时间晚于a[i+1]和a[i+2]的开始时间,必弃a[i]
            if(j-i>2)
            {
                //当前面已有课程被舍去,OK为假.
                if(k)
                {
                    OK=0;
                    break;
                }
                else
                {
                    pos[k]=a[i].idx;
                    //当后面仍有课程必须舍弃,OK也为假
                    for(i++;i<n && a[i].e<=a[i+1].s;i++){}
                    if(i<n)
                    {
                        OK=0;
                    }
                    break;
                }
            }
            //这时a[i]的结束时间大于且仅大于a[i+1]的开始时间,两者要舍去其一
            else if(j-i==2)
            {
                //当前面已有课程被舍去,OK为假.
                if(k)
                {
                    OK=0;
                    break;
                }
                else
                {
                    //当>2时a[i+1]必定要舍去;当==2时,a[i+1]和a[i+2]必弃其一,又结合
                    //a[i]和a[i+1]必弃其一,则还是只能舍弃a[i+1].
                    if(check(i+1)-(i+1)>=2)
                    {
                        pos[k++]=a[i+1].idx;
                    }
                    else if(i>0 && a[i-1].e>a[i+1].s)
                    {
                        pos[k++]=a[i+1].idx;
                    }
                    //此时a[i+1].e<=a[i+2].s,a[i],a[i+1]都可以选为被舍弃的组。
                    else
                    {
                        pos[k++]=a[i].idx;
                        pos[k++]=a[i+1].idx;
                    }
                    i++;
                }
            }
        }
        if(!OK) puts("0");
        //ok==1但k==0
        else if(!k)
        {
            printf("%d\n",n);
            for(i=1;i<n;i++)
                printf("%d ",i);
            printf("%d\n",i);
        }
        else
        {
            sort(pos,pos+k);
            printf("%d\n",k);
            for(i=0;i<k-1;i++)
                printf("%d ",pos[i]);
            printf("%d\n",pos[i]);
        }
        return 0;
    }



  • 相关阅读:
    7、NFC技术:让Android自动运行程序
    6、Android中的NFC技术
    5、NFC概述
    Delphi XE7中开发安卓程序一些有用的帮助资源
    Delphi开发安卓程序的感受
    Tomcat绿色版启动"startup.bat"一闪问题的解决方法!
    Delphi判断字符串中是否包含汉字,并返回汉字位置
    Delphi的DLL里如何实现定时器功能?
    Delphi的DLL里如何实现定时器功能?
    VS2013如何添加LIb库及头文件的步骤
  • 原文地址:https://www.cnblogs.com/cszlg/p/2910587.html
Copyright © 2011-2022 走看看