CCF201503-3 节日 JAVA实现

CCF201503-3 节日 JAVA实现

201503-3

问题描述
  有一类节日的日期并不是固定的,而是以“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。

以下是代码

“`
import java.util.Scanner;

public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
final int month = input.nextInt(), count = input.nextInt(), week_id = input.nextInt();
final int startYear = input.nextInt(), endYear = input.nextInt();
input.close();

    //得到给定月份的第一天与一月一日相隔几天
    //这里没有判断是否为闰年 留作以后处理
    final int days;
    switch (month) {
    case 1:
        days = 0;
        break;
    case 2:
        days = 31;
        break;
    case 3:
        days = 59;
        break;
    case 4:
        days = 90;
        break;
    case 5:
        days = 120;
        break;
    case 6:
        days = 151;
        break;
    case 7:
        days = 181;
        break;
    case 8:
        days = 212;
        break;
    case 9:
        days = 243;
        break;
    case 10:
        days = 273;
        break;
    case 11:
        days = 304;
        break;
    case 12:
        days = 334;
        break;
    default:
        days = 0;
        break;
    }

    //得到起始年份第一天与1850年第一天相隔的天数
    int dayFrom1850 = 0, leapYearMod = 0;//闰年判断标志 1852是闰年
    //如果startYear与1850相隔4的整数倍,则startYear+2是闰年,startYear+4+2也是闰年,以此类推
    if ((startYear - 1850) % 4 == 0) {
        //中间隔了((startYear - 1850) / 4)个四年
        dayFrom1850 = ((startYear - 1850) / 4) * (366 + 365 * 3);
        leapYearMod = 2;
    //如果startYear与1850除4余1,则startYear+1是闰年,startYear+4+1也是闰年,以此类推
    } else if ((startYear - 1850) % 4 == 1) {
        leapYearMod = 1;
        //中间隔了((startYear - 1850) / 4)个四年 还多一个平年
        dayFrom1850 = ((startYear - 1850) / 4) * (366 + 365 * 3) + 365;
    } else if ((startYear - 1850) % 4 == 2) {
        leapYearMod = 0;
        //中间隔了((startYear - 1850) / 4)个四年 还多一个平年,一个闰年
        dayFrom1850 = ((startYear - 1850) / 4) * (366 + 365 * 3) + 365 + 366;
    } else {
        leapYearMod = 3;
        //中间隔了((startYear - 1850) / 4)个四年 还多两个平年,一个闰年
        dayFrom1850 = ((startYear - 1850) / 4) * (366 + 365 * 3) + 365 + 366 + 365;
    }
    if (startYear > 1900) {
        dayFrom1850--;//1900不是闰年 所以减掉1
    }
    //得到起始年份的第一天是星期几
    //提交一直80分,后来发现 是这里出的问题
    //直接写为 dayFrom1850 % 7 +2 有可能会大于7
    int firstDayOfYear = (dayFrom1850 % 7 + 1)%7+1;
    //存放结果集 (其实可以直接在第一次循环里输出QAQ)
    String[] resultDays = new String[endYear - startYear + 1];

    for (int i = startYear; i <= endYear; ++i) {
        //days每次循环都要用,所以设置为Final
        int thisDays = days;
        //如果是闰年的3月后 天数加一 
        //因为在题设范围内除四为0且不为闰年的年只有1900 所以这里偷懒了
        if (month > 2 && (i - startYear) % 4 == leapYearMod && i != 1900) {
            thisDays++;
        }
        //当前年指定月份的一日
        int month1week = (thisDays % 7 + firstDayOfYear-1) % 7 +1;

        //得到目标天数
        int temp = 0;
        if (month1week > week_id) {
            temp = 8-month1week + (count - 1) * 7 +week_id;
        } else {
            temp =  (count - 1) * 7 +week_id - month1week + 1 ;
        }

        //将目标天存入结果集
        resultDays[i - startYear] = temp + "";
        if (temp < 10)
            resultDays[i - startYear] = "0" + resultDays[i - startYear];

        //得到下一年第一天是星期几;
        firstDayOfYear = (365 % 7 + firstDayOfYear-1)%7 +1;
        if ((i - startYear) % 4 == leapYearMod && i != 1900) {
            firstDayOfYear=(firstDayOfYear)%7 +1;
        }
    }


    //这里貌似用format输出更合适(还是不会?
    String monthprint = month + "";
    if (monthprint.length() == 1)
        monthprint = "0" + monthprint;//month转换为字符串
    for (int i = 0; i < resultDays.length; i++) {
        switch (month) {
        case 1:
        case 3:
        case 5:
        case 7:
        case 8:
        case 10:
        case 12:
            if (Integer.valueOf(resultDays[i]) <= 31)
                System.out.println((startYear + i) + "/" + monthprint + "/" + resultDays[i]);
            else {
                System.out.println("none");
            }
            break;
        case 4:
        case 6:
        case 9:
        case 11:
            if (Integer.valueOf(resultDays[i]) <= 30)
                System.out.println((startYear + i) + "/" + monthprint + "/" + resultDays[i]);
            else {
                System.out.println("none");
            }
            break;
        case 2:
            int febDay = 28;
            if (i % 4 == leapYearMod && i + startYear != 1900)
                febDay++;
            if (Integer.valueOf(resultDays[i]) <= febDay)
                System.out.println((startYear + i) + "/" + monthprint + "/" + resultDays[i]);
            else {
                System.out.println("none");
            }
            break;
        }
    }
}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值