限时模拟:猫猫睡觉问题

Posted muxin2333

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了限时模拟:猫猫睡觉问题相关的知识,希望对你有一定的参考价值。

1.题意简介:TT家的魔法猫十分嗜睡,睡觉的时段是连续的,可以假设喵喵必须要睡眠连续不少于 A 个小时,即一旦喵喵开始睡觉了,至少连续 A 个小时内(即A*60分钟内)不能被打扰,并且它一次性不能连续活动超过 B 个小时。现在魔法猫要上B站追番,新番的播放时间已知,看新番的时候必须是醒着的。现在请你帮它安排睡觉的时间段。

输入格式:

多组数据,每组数据的格式如下:

第1行输入三个整数,A 和 B 和 N (1 <= A <= 24, 1 <= B <= 24, 1 <= n <= 20)

第2到N+1行为每日的新番时间表,每行一个时间段,格式形如 hh:mm-hh:mm (闭区间),这是一种时间格式,hh:mm 的范围为 00:00 到 23:59。注意一下,时间段是保证不重叠的,但是可能出现跨夜的新番,即新番的开始时间点大于结束时间点。

保证每个时间段的开始时间点和结束时间点不一样,即不可能出现类似 08:00-08:00 这种的时间段。时长的计算由于是闭区间所以也是有点坑的,比如 12:00-13:59 的时长就是 120 分钟。

不保证输入的新番时间表有序。

要求输出:

输出的第一行是 Yes 或者 No,代表是否存在满足猫猫要求的时间管理办法

第2行输出一个整数 k,代表当天有多少个时间段要睡觉

接下来 k 行是喵喵的睡觉时间段,每行一个时间段,格式形如 hh:mm-hh:mm (闭区间),这个在前面也有定义。注意一下,如果喵喵的睡眠时段跨越当天到达了明天,比如从23点50分睡到0点40分,那就输出23:50-00:40,如果从今晚23:50睡到明天早上7:30,那就输出23:50-07:30。

2.思路分析:本题最主要的地方在于计算出两部新番之间的时间间隔,然后根据给出的睡眠时间A和活动时间B进行是否可以睡觉的判断。根据题意,可以给出两个存储空间,一个存储睡觉时间t1,一个存储看番时间t,而睡觉时间就可以根据两个相邻看番时间之间的空隙来计算。另外是要注意跨过两天的“熬夜番”的时间计算要特殊处理一下。

计算时间:全部转换为分钟来进行处理,方便比较,输出结果时再还原为指定的格式即可。

判断能否睡觉:首先由于睡觉的时间是连续的,且不能小于A小时,所以计算出来的两部新番之间的睡觉时间time可能有两种情况:大于A或者小于A;大于A,表示可以睡觉;小于A,表示不能睡觉,此时这一段时间(即两部新番的播出时间和中间的空隙)都要看做活动时间,这个时候进行time和活动时间B的比较,如果time>B,那么就说明这段时间无法合理安排作息,那么直接输出No即可;如果time<=B,那么就说明这段时间是可以进行活动的,然后进行下一次睡觉时间的计算和比较。

3.代码:

#include <iostream>
#include <cstring>
#include <math.h>
#include <algorithm>
using namespace std;

struct time
{
    int start;
    int end;
    int last;//时长 
    int can_sleep;
    bool operator <(const time &t)
    {
        if(start<t.start)
            return true;
        else return false;
    }
}; 
time t[10000];//看番时间
time t1[10000];//睡觉时间 
int a,b,n;
int j;

int get_time(string ti)
{//计算看番时间 
    int sum1=0;
    int sum2=0;
    for(int i=0;i<5;i++)
    {//开始时间 
        if(ti[i]>=0 && ti[i]<=9)
        {
            int a=ti[i]-0;
            //cout<<a<<endl;
            if(i<=1)
            {
                sum1=sum1+a*pow(10,1-i);
            }
            else if(i>=3)
            {
                sum2=sum2+a*pow(10,4-i);
            }
        }
    }
    int sum=sum1*60+sum2;
    t[j].start=sum;
    sum1=sum2=sum=0;
    for(int i=6;i<11;i++)
    {//结束时间 
        if(ti[i]>=0 && ti[i]<=9)
        {
            int a=ti[i]-0;
            if(i<=7)
            {
                sum1=sum1+a*pow(10,7-i);
            }
            else if(i>=9)
            {
                sum2=sum2+a*pow(10,10-i);
            }
        }
    }
    sum=sum1*60+sum2;
    t[j].end=sum;
    if(t[j].end<t[j].start)
    {//时长 
        int last_time=1440-t[j].start+t[j].end;
        t[j].last=last_time+1;
        if(t[j].last>b)
        return -1;
    }
    else
    {
        t[j].last=t[j].end-t[j].start+1;
        if(t[j].last>b)
        return -1;
    }
    //cout<<t[j].last<<endl;
    j++;
    return 1;
}

int judge()
{
    sort(t,t+j);
    j--; 
    for(int i=0;i<n;i++)
    {//计算睡觉时间 
        if(i>=1)
        {
            //开始 
            if(t[i-1].end==1439)
            {
                t1[i].start=0;
            }
            else t1[i].start=t[i-1].end+1;
            //结束 
            if(t[i].start==0)
            {
                t1[i].end=1439;
            }
            else t1[i].end=t[i].start-1;
            //时长 
            if(t1[i].end<t1[i].start)
            {
                int last_time=1440-t1[i].start+t1[i].end;
                t1[i].last=last_time+1;
            }
            else t1[i].last=t1[i].end-t1[i].start+1;
            if(t1[i].last<a)
            t1[i].can_sleep=-1;
        }
        else
        {
            if(t[0].start==0)
            {
                if(t[0].last>b)
                return -1;
                else
                {
                    t1[0].start=t[0].end+1;
                    t1[0].end=t[1].start-1;
                    t1[0].last=t1[0].end-t1[0].start+1;
                    if(t1[0].last<a)
                    t1[0].can_sleep=-1;
                }
            }
            else
            {
                if(t[j].end==1439)
                {
                    t1[0].start=0;
                }
                else t1[0].start=t[j].end+1;
                if(t[0].start==0)
                {
                    t1[0].end=1439;
                }
                else t1[0].end=t[0].start-1;
                if(t1[0].end<t1[0].start)
                {
                    t1[0].last=1440-t1[0].start+t1[0].end+1;
                    if(t1[0].last<a)
                    t1[0].can_sleep=-1;//虽然没有看番,但是时间不够 
                }
                else
                {
                    t1[0].last=t1[0].end-t1[0].start+1;
                    if(t1[0].last<a)
                    t1[0].can_sleep=-1;
                }
            }
            
        }
        //cout<<t1[i-1].last<<endl;
    }
    for(int i=0;i<n;i++)
    {
        int length=0;
        if(t1[i].can_sleep==-1)
        {
            if(i==0)
            {
                length=t[j].last+t1[i].last+t[i].last;
                if(length>b)
                return -1;
            }
            else
            {
                length=t[i-1].last+t1[i].last+t[i].last;
                if(length>b)
                return -1;
            }
        }
        else
        {
            continue;
        }
    }
    return 1;
}

int main()
{
    while(cin>>a)
    {
    j=b=n=0;
    cin>>b>>n;
    a=a*60;
    b=b*60;
    int c=1;
    for(int i=0;i<n;i++)
    {
        string s;
        cin>>s;
        c=get_time(s);
        if(c==-1)
        break;
    }
    if(c==-1)
    {
        cout<<"No"<<endl;
        return 0;
    }
    else
    {
        c=judge();
        if(c==-1)
        {
            cout<<"No"<<endl;
            return 0;
        }
        else
        {
            cout<<"Yes"<<endl;
            for(int i=0;i<n;i++)
            {
                //cout<<"sleep:"<<t1[i].can_sleep<<endl;
                if(t1[i].can_sleep!=-1)
                {
                    //开始 
                    int h=t1[i].start/60;
                    if(h<=9)
                    cout<<"0"<<h<<":";
                    else
                    cout<<h<<":";
                    int m=t1[i].start%60;
                    if(m<=9)
                    cout<<"0"<<m<<"-";
                    else
                    cout<<m<<"-"; 
                    //结束
                    int h1=t1[i].end/60;
                    if(h1<=9)
                    cout<<"0"<<h1<<":";
                    else
                    cout<<h1<<":";
                    int m1=t1[i].end%60;
                    if(m1<=9)
                    cout<<"0"<<m1<<endl;
                    else
                    cout<<m1<<endl;    
                }     
            }
        }
    }
    }
}

 

以上是关于限时模拟:猫猫睡觉问题的主要内容,如果未能解决你的问题,请参考以下文章

第十周 限时模拟

第十周 限时模拟

睡觉请关灯   游戏模拟实现

如何以毫秒为单位获取javaFX音频片段的长度[关闭]

Week10 限时大模拟 B - 东东转魔方 HDU - 5983

猫猫学iOS之UIButton一行代码重写图片和标题位置