正好做到这一道布置的选做题,也是在debug了差不多一个小时后才通过所有实例。
不愧是学校布置的题目的隐藏示例,我都不知道错在哪里,啥都保密。
题目如下:
再次给出任意一个年月日(年>1900),现在我们不能只是直接计算,要先判断给出的日期是否合法,对于非法的日期要给出错误提示信息,合法的日期要再计算是星期几。
输出:0~6。
星期日用 0 表示,星期一用 1 表示,星期二用 2 表示......星期六用 6 表示
对于月份,日期不合法的,需要输出相应语句,即"month is error"或者"day is error"
先给出我的算法:
比起其他大佬那些用公式暴力秒杀的,我发现那更适合对原始算法的优化,我这里就给出适合教学进度的基础算法,不能保证高效,但是都是正确的。
首先是判断一年是否是闰年,这个可以使用一个bool类型的函数,如下:
bool iffrun(int n)
{
if((n%4==0&&n%100!=0)||n%400==0)
{
return true;
}
return false;
}
然后是对于输入年份之前出现的闰年数量的统计,可以利用上面这一个函数进行遍历:
这样调用了上面的判断函数。
int ifrun(int start,int end)
{
int i=0;
int count=0;
for(i=start;i<end;i++) // start 可以规定成1900,遍历刀输入年份的前一年
{
if(iffrun(i))
{
count++;
}
}
return count;
}
既然讲到了这里的算法,我就先介绍我对统计天数的算法,最暴力的算法之一:
这个算法主要考虑的就是计算整年,整月,最后再加上日期里面的days,注意着重考虑闰年对一年的天数和二月份的天数的影响即可。
else
{
int res=ifrun(1900,a); // 统计闰年的个数
int num=365*(a-1900)+res; // 闰年多一天,闰年总个数
int i=b-1; // b 是月份,这个月还没过完
while(i)
{
switch(i) // 对月份的循环,算出整月的天数,注意二月的天数需要考虑输入年
{
case 1:num+=31;break;
case 2:num+=iffrun(a)?29:28;break;
case 3:num+=31;break;
case 4:num+=30;break;
case 5:num+=31;break;
case 6:num+=30;break;
case 7:num+=31;break;
case 8:num+=31;break;
case 9:num+=30;break;
case 10:num+=31;break;
case 11:num+=30;break;
case 12:num+=31;break;
}
i--; // 月份调整
}
num+=c-1; // 加上输入的日期,最后再减一,这是减去1900/1/1,数学脑经急转弯
int k=(num+1)%7; // 算出星期几
printf("%d\n",k);
}
最后来到让我难受半个多小时的debug合法日期:
首先是月份需要大于0小于13,对于我这个算法,如果输入的月份是0,那么就会运行超时,这个错误有在我的结果报告出现过
然后就是天数,大月天数小于32,小月天数小于31,平二月天数小于29,闰二月天数小于30,所有的天数都要大于0,这就是所有条件:
if(b>12||b<1)
{
printf("month is error.\n");
}
else if((b==2&&iffrun(a)&&c>29)||(b==2&&(!iffrun(a))&&c>28)||((b==4||b==6||b==9||b==11)&&c>30)||c>31||c<1)
{
printf("day is error.\n");
}
文章结尾,我附上全部AC的代码,仅供参考,学术诚信:
如有错误,请斧正!
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
#include<math.h>
#include<stdbool.h>
bool iffrun(int n)
{
if((n%4==0&&n%100!=0)||n%400==0)
{
return true;
}
return false;
}
int ifrun(int start,int end)
{
int i=0;
int count=0;
for(i=start;i<end;i++)
{
if((i%4==0&&i%100!=0)||i%400==0)
{
count++;
}
}
return count;
}
int main()
{
int a,b,c;
scanf("%d %d %d",&a,&b,&c);
if(b>12||b<1)
{
printf("month is error.\n");
}
else if((b==2&&iffrun(a)&&c>29)||(b==2&&(!iffrun(a))&&c>28)||((b==4||b==6||b==9||b==11)&&c>30)||c>31||c<1)
{
printf("day is error.\n");
}
else
{
int res=ifrun(1900,a);
int num=365*(a-1900)+res;
int i=b-1;
while(i)
{
switch(i)
{
case 1:num+=31;break;
case 2:num+=iffrun(a)?29:28;break;
case 3:num+=31;break;
case 4:num+=30;break;
case 5:num+=31;break;
case 6:num+=30;break;
case 7:num+=31;break;
case 8:num+=31;break;
case 9:num+=30;break;
case 10:num+=31;break;
case 11:num+=30;break;
case 12:num+=31;break;
}
i--;
}
num+=c-1;
int k=(num+1)%7;
printf("%d\n",k);
}
return 0;
}