洛谷 P1167 刷题

洛谷 P1167 刷题

洛谷传送门

题目描述

noip临近了,小A却发现他已经不会写题了。好在现在离竞赛还有一段时间,小A决定从现在开始夜以继日地刷题。也就是说小A废寝忘食,一天二十四小时地刷题。

今天的日期(时间)是yyyyyyy**y年mmm**m月ddd**d日hhh**h时minmin分,考试的时间是yyyyyyy**y'年mmm**m'月ddd**d'日hhh**h'时minmin'分。这之间的所有时间小A都用来刷题了,那么考试之前他最多能刷多少题呢?注意哦,考虑闰年。

时间紧张小A只管数量不管质量。当然有的题目容易一些,有的题目难一些。根据小A的经验,他能一眼看出写出某一个题目需要的时间,以分钟记。

现在给出洛谷Online Judge的题目列表,请你挑出最多的题目使小A能在竞赛前写出来。

我们假设从远古到未来,历法的表示与现在一样。

输入格式

第一行一个整数NN,表示洛谷Online Judge的题目数,N≤5000N≤5000。

接下来NN行,每行一个整数表示刷该题需要用的时间,以分钟记(le 10000≤10000)。(这个题本身是什么并不重要,不是么?小A已经写过题目数为00个)。

接下来两行依次是当前时间和竞赛时间。时间给出的格式是:yyyy-mm-dd-hh:minyyy**ym**md**dh**h:min,例如:2007-06-23-02:002007−06−23−02:00,采用2424小时制,每天从00:00~23:59,年份从00000000到99999999。

输出格式

一行,一个整数,noip前最多刷的题目数。

输入输出样例

输入 #1复制

输出 #1复制

题解:

一道模拟题,加了一点点的贪心。

其实这题的贪心非常好想,就是时间少的先来,直接排序扫就可以。

带着这个思路,我们过来写代码:

然后我们发现我们卡在时间的处理上了...果然我还是蒟蒻

所以我在这里主要介绍一下这些“日期题”的处理技巧。

首先是读入,针对于这种读入,我们用字符串处理再从字符串中提取实在是麻烦的要命。所以我们直接用一种简化的方式:

scanf("%d-%d-%d-%d:%d",&start[1],&start[2],&start[3],&start[4],&start[5]);
scanf("%d-%d-%d-%d:%d",&endd[1],&endd[2],&endd[3],&endd[4],&endd[5]);

不用担心这种方法会爆锅,根本不可能,简单好用,骗分首选

读入完事了,接下来我们需要把这个时间段处理成分钟数(这样才能贪心)。

我给大家介绍两种方法把这个时间段分钟数处理出来。

第一种做法:

我们以0000年1月1日的00:00分做基准线(也不知道这时候基督这小家伙出生没),分别用起始日期和结束日期减去这个基准,然后就处理出了这个时间段(有一点点前缀和的味道)

然鹅我并没有这么做

第二种做法:

实在是惭愧,本蒟蒻只能想到最朴实无华的模拟方法。你想啊,我们可以先处理出天数然后×1440(24*60,一天的分钟数),然后再处理每天的分钟。

然后我们又想到,可不可以逐次处理年月日,最后再一点点的多退少补(注意这4个字!!)呢?

当然可以!!

我们先从起始年到终止年(注意不能<=终止年而要减去1即<终止年,下同)

如果是闰年就加上366天,否则加365天。

然后我们会发现,我们多处理了起始年的前半年,少处理了终止年的前半年。

这就是多退少补的思想了。先判闰年,用两个月份数组处理。

同理,我们多处理了起始月的前半个月,少处理了终止月的前半个月。

所以我们继续多退少补。

最后处理小时和分钟。

贪心的部分我就不讲了,这道题的难点已经说完了,这道题的贪心如果想不出来还是退役多练练吧。

注意一下:我一开始WA了两个大数据的点,是因为最后输出的时候,直接在else里输出,这样如果是极大数据的话,根本就进不去else那里,导致输出为空,请大家引以为戒。

代码:

#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
int n,time,ans;
int a[5010];
int m1[]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int m2[]={0,31,29,31,30,31,30,31,31,30,31,30,31};
int start[10],endd[10];
bool check(int x)
{
    if((x%4==0 && x%400!=0) || x%400==0)
        return 1;
    return 0;
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);
    sort(a+1,a+n+1);
    scanf("%d-%d-%d-%d:%d",&start[1],&start[2],&start[3],&start[4],&start[5]);
    scanf("%d-%d-%d-%d:%d",&endd[1],&endd[2],&endd[3],&endd[4],&endd[5]);
    for(int i=start[1];i<endd[1];i++)
    {
        if(check(i))
            time+=366;
        else
            time+=365;
    }
    if(check(start[1]))
        for(int i=1;i<start[2];i++)
            time-=m2[i];
    else
        for(int i=1;i<start[2];i++)
            time-=m1[i];
    if(check(endd[1]))
        for(int i=1;i<endd[2];i++)
            time+=m2[i];
    else
        for(int i=1;i<endd[2];i++)
            time+=m1[i];
    for(int i=1;i<start[3];i++)
        time--;
    for(int i=1;i<endd[3];i++)
        time++;
    time=time*24*60;
    time-=60*start[4]+start[5];
    time+=60*endd[4]+endd[5];
    for(int i=1;i<=n;i++)
    {
        if(time>=a[i])
        {
            time-=a[i];
            ans++;
        }
        else
            break;
    }
    printf("%d",ans);
    return 0;
}
原文地址:https://www.cnblogs.com/fusiwei/p/11386619.html