题目描述
NOIP 临近了,小 A 却发现他已经不会写题了。好在现在离竞赛还有一段时间,小 A 决定从现在开始夜以继日地刷题。也就是说小 A 废寝忘食,一天二十四小时地刷题。
今天的日期(时间)是 yyyy 年 mm 月 dd 日 hh 时 MM 分,考试的时间是 yyyy2 年 mm2 月 dd2 日 hh2 时 MM2 分。这之间的所有时间小 A 都用来刷题了,那么考试之前他最多能刷多少题呢?注意哦,考虑闰年。
时间紧张小 A 只管数量不管质量。当然有的题目容易一些,有的题目难一些。根据小 A 的经验,他能一眼看出写出某一个题目需要的时间,以分钟记。
现在给出洛谷 Online Judge 的题目列表,请你挑出最多的题目使小A能在竞赛前写出来。
我们假设从远古到未来,历法的表示与现在一样。
输入格式
第一行一个整数 N,表示洛谷 Online Judge 的题目数,N≤5000。
接下来N行,每行一个整数表示刷该题需要用的时间,以分钟记(≤10000)。(这个题本身是什么并不重要,不是么?小A
已经写过题目数为 0 个)。
接下来两行依次是当前时间和竞赛时间。时间给出的格式是:yyyy-mm-dd-hh:MM
,例如:2007-06-23-02:00
,采用 24 小时制,每天从 00:00 到 23:59,年份从 0000 到 9999。
输出格式
一行,一个整数,NOIP 前最多刷的题目数。
输入输出样例
输入
2 1 1 2007-06-23-11:59 2007-06-23-12:00
输出
1
测试点5(有点长)
输入
100 7132 5111 638 7836 3809 1278 9578 7590 8245 5903 7611 4788 6810 1510 3564 3359 6412 996 4966 9801 5807 678 9175 9386 4146 1825 4869 9384 3639 2305 8130 1178 5102 2193 1739 1643 2965 7246 7051 2416 3779 5516 4395 3418 4869 9815 6073 5015 8501 210 3966 4891 8993 2883 5513 3775 799 9986 8190 4664 4361 241 7681 6235 7153 8032 8875 19 9254 1943 2049 8302 1848 9176 8699 6579 8112 4443 5158 8833 9849 6449 3882 2753 4101 1130 9517 4540 5516 9757 1047 3314 2938 576 8635 9440 8509 8 2596 3815 2007-02-05-00:00 2007-03-28-00:00
输出
36
思路:
1.首先确定我们的思路,多去少补,即把开始年份的一整年算上,最后再把多算的时间去掉,不算最后年份的一整年,只算多出来那一部分。
2.要处理闰年的问题,就得知道闰年的定义,然后把年份转为天数。
int ifrunnian(int x)是否为闰年
{
if(x%4==0)
{
if(x%400==0) return 366;
if(x%100==0) return 365;
return 366;
}
return 365;
}
3.把月份转为天数,记得闰年的二月多加一天,还有当月份为1时,直接退出循环,郑则我们直接拿他输入的天数就行,毕竟一月一号,实际上只有一号这一天,所以就算月份不为1,循环也不能涉及最后一个月。
int month[]={0,31,28,31,30,31,30,31,31,30,31,30,31};月份数组
for(int i=1;i<m1;i++)
{
if(m1==1) break;
ds+=month[i];
if(i==2&&ifrunnian(y1)==366) ds++;
}
for(int i=1;i<m2;i++)
{
if(m2==1) break;
de+=month[i];
if(i==2&&ifrunnian(y2)==366) de++;
}
4。还有一点点贪心,对做题时间进行简单的排序,先做时间少的
AC code
#include <iostream>
#include <algorithm>
using namespace std;
int n;
int q[10010];
int y1,m1,d1,h1,fen1;
int y2,m2,d2,h2,fen2;
int res;
int dd;记录年份之间差的天数
int ifrunnian(int x)闰年判断
{
if(x%4==0)
{
if(x%400==0) return 366;
if(x%100==0) return 365;
return 366;
}
return 365;
}
int main()
{
cin>>n;
for(int i=0;i<n;i++)
{
cin>>q[i];
}
int month[]={0,31,28,31,30,31,30,31,31,30,31,30,31};
scanf("%d-%d-%d-%d:%d",&y1,&m1,&d1,&h1,&fen1);
scanf("%d-%d-%d-%d:%d",&y2,&m2,&d2,&h2,&fen2);
sort(q,q+n);
for(int i=y1;i<y2;i++)
{
dd+=ifrunnian(i);
}
int ds,de;
//计算月份转天数
for(int i=1;i<m1;i++)
{
if(m1==1) break;
ds+=month[i];
if(i==2&&ifrunnian(y1)==366) ds++;
}
for(int i=1;i<m2;i++)
{
if(m2==1) break;
de+=month[i];
if(i==2&&ifrunnian(y2)==366) de++;
}
int oi=(dd+de+d2-ds-d1)*1440+(h2-h1)*60+fen2-fen1;
for(int i=0;i<n;i++)
{
if(q[i]>oi) break;
if(q[i]<=oi) res++,oi-=q[i];
}
cout<<res<<endl;
return 0;
}