• 节日(CCF试题)


    试题编号:    201503-3
    试题名称:    节日
    时间限制:    1.0s
    内存限制:    256.0MB
    问题描述
      有一类节日的日期并不是固定的,而是以“a月的第b个星期c”的形式定下来的,比如说母亲节就定为每年的五月的第二个星期日。
      现在,给你a,b,c和y1, y2(1850 ≤ y1, y2 ≤ 2050),希望你输出从公元y1年到公元y2年间的每年的a月的第b个星期c的日期。
      提示:关于闰年的规则:年份是400的整数倍时是闰年,否则年份是4的倍数并且不是100的倍数时是闰年,其他年份都不是闰年。例如1900年就不是闰年,而2000年是闰年。
      为了方便你推算,已知1850年1月1日是星期二。
    输入格式
      输入包含恰好一行,有五个整数a, b, c, y1, y2。其中c=1, 2, ……, 6, 7分别表示星期一、二、……、六、日。
    输出格式
      对于y1和y2之间的每一个年份,包括y1和y2,按照年份从小到大的顺序输出一行。
      如果该年的a月第b个星期c确实存在,则以"yyyy/mm/dd"的格式输出,即输出四位数的年份,两位数的月份,两位数的日期,中间用斜杠“/”分隔,位数不足时前补零。
      如果该年的a月第b个星期c并不存在,则输出"none"(不包含双引号)。
    样例输入
    5 2 7 2014 2015
    样例输出
    2014/05/11
    2015/05/10
    评测用例规模与约定
      所有评测用例都满足:1 ≤ a ≤ 12,1 ≤ b ≤ 5,1 ≤ c ≤ 7,1850 ≤ y1, y2 ≤ 2050
     
    分析:擦啊,真的是够了,这道题让我纠结了一个整整上午的时间。我一直认为自己的答案是正确的,找到样例都是可以通过的。可是一直是40%的通过率,头都快炸了。最后,我感觉是这道题有问题。而问题就是题目中给的描述:如果该年的a月第b个星期c并不存在,则输出"none"(不包含双引号)。
    我擦啊,正常人该怎么去理解这句话(红色部分的)?好,下面举个例子来说明这句话:
    这个可是标准日历,从日历显示中我们可以知道,2016年1月的第一个星期的星期五是1月1号,那么第一个星期还会存在星期1,2,3,4吗?不可能吧,因为2016年的1月1号是从第一个星期的周五开始的。所以说如果输入:1 1 4 2016 2016,那么会输出"none"。对不对,对不对,对不对,同志们,正常理解应该是这样的吧。
    好了,我就将红色的那句话作为一个不存在的判断条件,对不,这可是题目给出的!
    好下面是我第一次写的代码,并提交了,结果判定为40分。真是想不通了,我擦啊,对照着日历一遍一遍输入数据,结果都是正确的啊!想不通,真是想不通。 
     
    #include "stdafx.h"
    #include <iostream>
    #include <stdio.h>
    using namespace std;
    const int YEAR = 1850;
    int flag = 0;
    //平年和闰年的月份所含的天数
    //daysOfMonth[0][]表示平年月份的天数
    //daysOfMonth[1][]表示闰年月份的天数
    int daysOfMonth[2][13] =
    {
        { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
        { 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
    };
    
    //判断是否为闰年
    void judgeIsLeapYear(int year)
    {
        if ((year % 400 == 0) || (year % 4 == 0 && year % 100 != 0))
            flag = 1;
        else
            flag = 0;
    }
    
    int cmpDays(int y, int m)
    {
        int days = 0;
        for (int i = YEAR; i < y; i++)
        {
            judgeIsLeapYear(i);
            if (flag == 1)
                days += 366;
            else
                days += 365;
        }
        judgeIsLeapYear(y);
        for (int i = 1; i <= m; i++)
            days += daysOfMonth[flag][i-1];
        return days;
    }
    
    int main()
    {
        int a, b, c, y1, y2;
        int d1, d2;
        int dth;//每月一号是星期几
        while (scanf("%d%d%d%d%d", &a, &b, &c, &y1, &y2) != EOF)
        {
            for (int i = y1; i <= y2; i++)
            {
                d1 = cmpDays(i, a);//与1850年1月1日相差的天数
                dth = d1 % 7 + 2;//当前a月1号是星期几
                if (dth == 0)
                    dth = 7;
                //计算a月第b个星期星期c的具体日期
                d2 = (b - 1) * 7 - dth + c + 1;
    
                if (b == 1 && c<dth || d2 > daysOfMonth[flag][b])
                {
                    printf("none
    ");
                    continue;
                }
    
                if (d2 <= daysOfMonth[flag][a])
                    printf("%d/%02d/%02d
    ", i, a, d2);
    
    
            }
        }
            return 0;
    }

    绞尽脑汁了,我擦,修改一下,这个还是看的网上的一篇文章进行修改的,原来第一个星期是存在歧义的。例如上面给的例子,2016年1月1号是周五,那么第一个星期的周四、周三、周二、周日要从下周开始算起,才是第一周。

    卧槽,真是一道废题啊,拜拜花费了那么多时间。在此更正本篇文章,以免更多人误解。

    #include "stdafx.h"
    #include <iostream>
    #include <stdio.h>
    using namespace std;
    const int YEAR = 1850;
    int flag = 0;
    //平年和闰年的月份所含的天数
    //daysOfMonth[0][]表示平年月份的天数
    //daysOfMonth[1][]表示闰年月份的天数
    int daysOfMonth[2][13] =
    {
        { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
        { 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
    };
    
    //判断是否为闰年
    void judgeIsLeapYear(int year)
    {
        if ((year % 400 == 0) || (year % 4 == 0 && year % 100 != 0))
            flag = 1;
        else
            flag = 0;
    }
    
    int cmpDays(int y, int m)
    {
        int days = 0;
        for (int i = YEAR; i < y; i++)
        {
            judgeIsLeapYear(i);
            if (flag == 1)
                days += 366;
            else
                days += 365;
        }
        judgeIsLeapYear(y);
        for (int i = 1; i <= m; i++)
            days += daysOfMonth[flag][i-1];
        return days;
    }
    
    int main()
    {
        int a, b, c, y1, y2;
        int d1, d2;
        int count;
        int dth;//每月一号是星期几
        while (scanf("%d%d%d%d%d", &a, &b, &c, &y1, &y2)!= EOF)
        {
            for (int i = y1; i <= y2; i++)
            {
                d1 = cmpDays(i, a);//与1850年1月1日相差的天数
                dth = d1 % 7 + 2;//当前a月1号是星期几
    
                //计算a月第b个星期星期c的具体日期
    //如果当前输入的星期c小于dth表示,第一周的星期c要从下一周算起。
    if (c < dth) count = 1; else count = 2; d2 = 8 - dth + (b - count) * 7 + c; if (d2 <= daysOfMonth[flag][a]) printf("%d/%02d/%02d ", i, a, d2); else printf("none "); } } return 0; }

    给出本人的提交记录:,尼玛都是泪啊,希望以后考试不要出现这样有歧义的题了,卡死人了!

  • 相关阅读:
    Vue学习路线
    国庆游
    Axure RP 9 Beta 开放下载(更新激活密钥和汉化包)
    python虚拟环境
    异步任务神器 Celery-入门
    pymysql操作mysql
    安装 RabbitMQ
    GIT工作流
    flask入门与发送邮件与QQ邮箱
    Mysql第一周
  • 原文地址:https://www.cnblogs.com/tgycoder/p/4989131.html
Copyright © 2020-2023  润新知