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