• 洛谷 P1167 刷题


    洛谷 P1167 刷题

    题目链接:洛谷 P1167 刷题

    算法标签: 贪心模拟

    题目

    题目描述

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

    今天的日期(时间)是yyyy年mm月dd日hh时min分,考试的时间是yyyy'年mm'月dd'日hh'时min'分。这之间的所有时间小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前最多刷的题目数。

    输入输出样例

    输入 #1

    2
    1
    1
    2007-06-23-11:59
    2007-06-23-12:00
    

    输出 #1

    1
    

    题解:

    最开始看到题解,就是很明显的贪心解法,保证在有限的时间内每次都取最小值即可(利用sort()),然而这道题难就难在了如何模拟的计算出总的分钟数。在模拟过程中有一些需要特别注意的东西:

    • 闰年
    • 每个月的天数
    • 如何读入???(scanf("%d-%d-%d-%d:%d",……)

    然而这时就需要复习一下对于闰年的判断:(每四年一闰,百年不闰,四百年再闰)

    bool run(int x)
    {
    	if (x % 100 == 0)
    	{
    		if (x % 400 == 0)
    			return 1;
    	}
    	else
    		if (x % 4 == 0)
    			return 1;
    	return 0;
    }
    

    接下来我们就模拟计算时间,计算时间中处理 “年”,“日”,“时”,“分”都是比较简单的,按照进制传给下一位即可,不过在“月”的判断中就比较复杂,要模拟计算,考虑每一个月的天数,并且考虑这一年(12个月)是否涉及到闰年的情况,具体实现见AC代码

    AC代码

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    using namespace std;
    struct _TIME{
    	int y, m, d, h, minn;
    }_time[3];
    int mon[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    bool run(int x)
    {
    	if (x % 100 == 0)
    	{
    		if (x % 400 == 0)
    			return 1;
    	}
    	else
    		if (x % 4 == 0)
    			return 1;
    	return 0;
    }
    int getminn(_TIME a, _TIME b)
    {
    	int ansy, ansm, ansd, ansh, ansminn;
    	ansy = b.y - a.y;
    	ansm = b.m - a.m;
    	ansd = b.d - a.d;
    	ansh = b.h - a.h;
    	ansminn = b.minn - a.minn;
    	if (ansy > 0)
    		ansm += ansy * 12;
    	if (ansm > 0)
    	{
    		int i = a.m, j = a.y;
    		for (int k = 1; k <= ansm; k ++ )
    		{
    			if (i > 12)
    			{
    				i -= 12;
    				j ++ ;
    			}
    			if (i == 1 && run(j))
    			{
    				ansd += mon[i - 1] + 1;
    				i ++ ;
    				continue ;
    			}
    			ansd += mon[i - 1];
    			i ++ ;
    		}
    	}
    	if (ansd > 0)
    		ansh += ansd * 24;
    	if (ansh > 0)
    		ansminn += ansh * 60;
    	return ansminn;
    }
    int num[5500];
    int n;
    int main()
    {
    	scanf("%d", &n);
    	for (int i = 1; i <= n; i ++ )
    		scanf("%d", &num[i]);
    	sort(num + 1, num + 1 + n);
    	scanf("%d-%d-%d-%d:%d", &_time[1].y, &_time[1].m, &_time[1].d, &_time[1].h, &_time[1].minn);
    	scanf("%d-%d-%d-%d:%d", &_time[2].y, &_time[2].m, &_time[2].d, &_time[2].h, &_time[2].minn);
    	int allminn = getminn(_time[1], _time[2]);
    	int cnt = 0;
    	for (int i = 1; i <= n; i ++ )
    	{
    		if (num[i] <= allminn)
    		{
    			cnt ++ ;
    			allminn -= num[i];
    		}
    		else
    			break ;
    	}
    	printf("%d
    ", cnt);
    	return 0;
    }
    
  • 相关阅读:
    算法演示工具
    1198:逆波兰表达式
    1315:【例4.5】集合的划分
    1192:放苹果
    1191:流感传染
    1354括弧匹配检验
    1331【例1-2】后缀表达式的值
    1307高精度乘法
    1162字符串逆序
    1161转进制
  • 原文地址:https://www.cnblogs.com/littleseven777/p/11842144.html
Copyright © 2020-2023  润新知