洛谷:刷题(P1167,贪心,闰年)

NOIP 临近了,小 A 却发现他已经不会写题了。好在现在离竞赛还有一段时间,小A决定从现在开始夜以继日地刷题。也就是说小 A 废寝忘食,一天二十四小时地刷题。
今天的日期(时间)是 yyyy 年 mm 月 dd 日 hh 时 min 分,考试的时间是 yyyy2 年 mm2 月 dd2 日 hh2 时 min2 分。这之间的所有时间小 A 都用来刷题了,那么考试之前他最多能刷多少题呢?注意哦,考虑闰年。
时间紧张小A只管数量不管质量。当然有的题目容易一些,有的题目难一些。根据小A的经验,他能一眼看出写出某一个题目需要的时间,以分钟记。
现在给出洛谷 Online Judge 的题目列表,请你挑出最多的题目使小A能在竞赛前写出来。
我们假设从远古到未来,历法的表示与现在一样。
输入格式 第一行一个整数N,表示洛谷Online Judge的题目数,N≤5000。
接下来N行,每行一个整数表示刷该题需要用的时间,以分钟记(≤10000)。(这个题本身是什么并不重要,不是么?小A已经写过题目数为0个)。
接下来两行依次是当前时间和竞赛时间。
时间给出的格式是:yyyy−mm−dd−hh:min,例如: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

#include       //本题的主要思路是把输入的时间差求出,排序题目所用时间,从小开始选择,直到时间不够
using namespace std;           
int a[10000];
int b[12]={31,28,31,30,31,30,31,31,30,31,30,31}; //存12个月日期
int fun1(int ,int );     //用来求出0年1月1日到现在要多加几天(共有几个闰年)
int fun(int year1,int year2,int month1,int month2,int day1,int day2,int hours1,int hours2,int minute1,int minute2){
    int countday1=0,countday2=0,sumday1=0,sumday2=0;
    countday1=fun1(year1,month1);      //求出因闰年而需要多加的天数
    countday2=fun1(year2,month2);
    for(int i=0;i<month1-1;i++){      //当前年份前几个月的天数
        sumday1+=b[i];
    }
    for(int i=0;i<month2-1;i++){
        sumday2+=b[i];
    }
    sumday1+=day1+countday1+365*year1;    //求出相对于0年1月1日的总天数,本来月日要减一因为相互抵消所以不计
    sumday2+=day2+countday2+365*year2;
    return (sumday2*24*60+hours2*60+minute2-sumday1*24*60-hours1*60-minute1);  //换算成分钟差返回
}
int fun1(int year,int month){
    int ans=0;
    for(int i=0;i<=year;i++){
        if(i%4==0&&i%100!=0||i%400==0){   //根据整4闰年整100非闰年整400闰年计算天数
            ans++;
        }
    }
    if(month<3&&(year%4==0&&year%100!=0||year%400==0)){   //当前时间下,如果是闰年但没过3月是不要加一的,
        ans--;           //上面多加了要减掉这步很关键,容易忽略
    }
    return ans;
}
int main(){
    int n;
    cin>>n;
    for(int i=0;i<n;i++){     //读入每题的时间
        cin>>a[i];
    }
    sort(a,a+n);        //排序
    int year1,year2,month1,month2,day1,day2,hours1,hours2,minute1,minute2;
    scanf("%d-%d-%d-%d:%d",&year1,&month1,&day1,&hours1,&minute1);
    scanf("%d-%d-%d-%d:%d",&year2,&month2,&day2,&hours2,&minute2);
    int ans=0;
    int total=0;
    total=fun(year1,year2,month1,month2,day1,day2,hours1,hours2,minute1,minute2);  //得到时间差
    for(int i=0;i<n;i++){
        if(a[i]<=total){
            ans++;
            total-=a[i];     //根据贪心策略,从耗时少的开始做,直到没时间或者没题目为止
        }
    }
    cout<<ans;
    //system("pause");
    return 0;
}

你可能感兴趣的:(洛谷:刷题(P1167,贪心,闰年))