问题 B: Day of Week
时间限制: 1 Sec内存限制: 32 MB提交: 135解决: 43
提交状态
题目描述
We now use the Gregorian style of dating in Russia. The leap years are years with number divisible by 4 but not divisible by 100, or divisible by 400.
For example, years 2004, 2180 and 2400 are leap. Years 2004, 2181 and 2300 are not leap.
Your task is to write a program which will compute the day of week corresponding to a given date in the nearest past or in the future using today’s agreement about dating.


输入
There is one single line contains the day number d, month name M and year number y(1000≤y≤3000). The month name is the corresponding English name starting from the capital letter.


输出
Output a single line with the English name of the day of week corresponding to the date, starting from the capital letter. All other letters must be in lower case.


样例输入
21 December 2012
5 January 2013
样例输出
Friday

Saturday



#include<stdio.h>
#include<string.h>
bool checkCommonYear(int a)
{
if (a % 4 == 0 && a % 100 != 0 || a % 400 == 0)
return false;
else
return true;
}//判断是否是平年
int MonthChange(char*b)
{
if (strcmp(b, "January") == 0)
return 1;
else if (strcmp(b, "February") == 0)
return 2;
else if (strcmp(b, "March") == 0)
return 3;
else if (strcmp(b, "April") == 0)
return 4;
else if (strcmp(b, "May") == 0)
return 5;
else if (strcmp(b, "June") == 0)
return 6;
else if (strcmp(b, "July") == 0)
return 7;
else if (strcmp(b, "August") == 0)
return 8;
else if (strcmp(b, "September") == 0)
return 9;
else if (strcmp(b, "October") == 0)
return 10;
else if (strcmp(b, "November") == 0)
return 11;
else if (strcmp(b, "December") == 0)
return 12;

}//将字符串月份转为整型月份
int main()
{
int days[13][2] = { {365,366},{31,31},{ 28,29 },{ 31,31 },{ 30,30 },{ 31,31 },
{ 30,30 },{ 31,31 },{ 31,31 },{ 30,30 },{ 31,31 },{ 30,30 },{ 31,31 } };//这个列出平年和闰年对应的每个月的天数
int day, year;//声明要接受输入的年月日
char month[20];//
while (scanf("%d %s %d",&day,month,&year) != EOF)
{
int dateInt = year * 10000 + MonthChange(month) * 100 + day;//将所输入的三个数据转化成整型日期
int temp,now = 20170105;//列出今天的整型日期为20170105,是星期四Thursday,作为计算其他日期是星期几的依据
bool flag = false;//用于判断所输的日期是不是比20170101大
if (dateInt > now)
{
flag = true;
temp = now;
now = dateInt;
dateInt = temp;
}//若输入的日期比20170105大那么将dateInt与now存储的内容交换,这样保证dateInt的数总比now中的小
int sum = 0;//用于存储日期差值
int y = dateInt / 10000, m = dateInt / 100 % 100, d = dateInt % 100;//再将整型日期分割成年月日存储到相应的变量中
int yn = now / 10000, mn = now / 100 % 100, dn = now % 100;//
for (int i = y; i < yn; i++)
{
if (checkCommonYear(i))
sum += days[0][0];
else
sum += days[0][1];
}//计算按年算差的天数,例如2012与2013差366天,因为2012是闰年
int sum1 = 0, sum2 = 0;//用于存储几月几号总共表示的天数,例如20121221,那么就统计1月1日到12月21日之间的总天数,两个端点都要各计一次
for (int i = 1; i < m; i++)
{
if (checkCommonYear(y))
{
sum1 += days[i][0];
}//若年数是平年那么按days中平年对应的月份天数来计算
else
sum1 += days[i][1];

}//该for循环统计月份之前的总天数,例如12月21日,那么统计1月1日到11月30日的总天数,两个端点都要各计一次
sum1 += d;//最后加上日数,例如12月21日,那么统计21日的总天数。这个sum1统计出较小日期的几月几日的总天数
for (int i = 1; i < mn; i++)
{
if (checkCommonYear(yn))
{
sum2 += days[i][0];
}
else
sum2 += days[i][1];

}
sum2 += dn;//统计出较大日期的几月几日的总天数
sum += sum2 - sum1;//算出日期差,其实这跟计算232和312两个数的差值道理相同,先从200到300差个100,那么差值先加上100,再由于12-32 = -20,那么差值再加上-20就得到总的差值80
sum %= 7;//将日期差模7便于处理星期几的问题
if (flag)//flag说明是要往前进行比还是往后进行比,当输入日期大时,发生交换,请看前面注释,那么从星期四往后比。
{
switch (sum)
{
case 0:
printf("Thursday\n"); break;//日期差模7后为0说明跟20170105的weekday是一样的
case 1:
printf("Friday\n"); break;
case 2:
printf("Saturday\n"); break;
case 3:
printf("Sunday\n"); break;
case 4:
printf("Monday\n"); break;
case 5:
printf("Tuesday\n"); break;
case 6:
printf("Wednesday\n"); break;
default:
break;
}
}
else//否则往前进行比较
{
switch (sum)
{
case 0:
printf("Thursday\n"); break;
case 1:
printf("Wednesday\n"); break;
case 2:
printf("Tuesday\n"); break;
case 3:
printf("Monday\n"); break;
case 4:
printf("Sunday\n"); break;
case 5:
printf("Saturday\n"); break;
case 6:
printf("Friday\n"); break;
default:
break;
}
}
}
return 0;
}