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;
}
}
}
}