第一题
题目描述:输入年月日,判断是该年第几天?
#include <stdio.h>
int leap_year(int n)
{
if(n%400==0||(n%4==0 && n%100!=0))
return 1;
else
return 0;
}
int main()
{
int year,month,day;
int dayCount=0,i;
int mon[]={0,31,28,31,30,31,30,31,31,30,31,30,31};
printf("请输入当前的年,月,日: ");
scanf("%d-%d-%d",&year,&month,&day);
for(i=1;i<month;i++)
dayCount+=mon[i];
if(month>2)
dayCount+=day+leap_year(year);
else
dayCount+=day;
printf("该日是该年的第几天: %d\n",dayCount);
return 0;
}
第二题
题目描述:给定年、月、日,计算该日是该年的第几天,并且计算该日是星期几。
#include <stdio.h>
int leap_year(int n)
{
if(n%400==0||(n%4==0 && n%100!=0))
return 1;
else
return 0;
}
int cal_dayCount(int year,int month,int day)
{
int i,sum;
int mon[]={0,31,28,31,30,31,30,31,31,30,31,30,31};
for(i=1,sum=0;i<month;i++)
sum+=mon[i];
if(month>2)
sum+=day+leap_year(year);
else
sum+=day;
return sum;
}
int cal_weekday(int year,int month,int day)
{
/**
蔡勒(Zeller)公式
历史上的某一天是星期几?未来的某一天是星期几?关于这个问题,有很多计算公式(两个通用计算公式和
一些分段计算公式),其中最著名的是蔡勒(Zeller)公式。
即w=y+[y/4]+[c/4]-2c+[26(m+1)/10]+d-1
公式中的符号含义如下,
w:星期;
c:年的高两位,即(世纪-1)
y:年的低两位;
m:月(m大于等于3,小于等于14,即在蔡勒公式中,某年的1、2月要看作上一年的13、14月来计算,
比如2003年1月1日要看作2002年的13月1日来计算);
d:日;
[ ]代表取整,即只要整数部分。
算出来的W除以7,余数是几就是星期几。如果余数是0,则为星期日。
如果结果是负数,负数求余数则需要特殊处理:
负数不能按习惯的余数的概念求余数,只能按数论中的余数的定义求余。为了方便
计算,我们可以给它加上一个7的整数倍,使它变为一个正数,然后再求余数
以2049年10月1日(100周年国庆)为例,用蔡勒(Zeller)公式进行计算,过程如下:
蔡勒(Zeller)公式:w=y+[y/4]+[c/4]-2c+[26(m+1)/10]+d-1
=49+[49/4]+[20/4]-2×20+[26× (10+1)/10]+1-1
=49+[12.25]+5-40+[28.6]
=49+12+5-40+28
=54 (除以7余5)
即2049年10月1日(100周年国庆)是星期5。
*/
int y, c, m, d;
int w;
if (month >= 3)
{
m = month;
y = year % 100;
c = year / 100;
d = day;
}
else /* 某年的1、2月要看作上一年的13、14月来计算 */
{
m = month + 12;
y = (year - 1) % 100;
c = (year - 1) / 100;
d = day;
}
w = y + y / 4 + c / 4 - 2 * c + (26*(m+1))/10 + d - 1;
if (w < 0) /* 如果w是负数,则计算余数方式不同 */
{
w = 7 - (-w) % 7;
}
else
{
w = w % 7; //如果w等于0,表示为星期天
}
return w;
}
int main()
{
int year,month,day;
int dayCount=0,i;
printf("请输入当前的年,月,日: ");
scanf("%d-%d-%d",&year,&month,&day);
printf("该日是该年的第几天: %d\n",cal_dayCount(year,month,day));
printf("该日是星期几: %d\n",cal_weekday(year,month,day));
return 0;
}
第三题
题目描述:现在已知2000年1月1日是星期六,给定一个正整数n,求出2000年1月1日之后n天的日期和星期。
#include <stdio.h>
#include <string.h>
#define STR_LEN 12
//获取某一年的天数
int YearDays(int year)
{
if ((year % 400 == 0) || (year % 4 == 0 && year % 100 != 0)) {
return 366;
} else {
return 365;
}
}
//获取某一月的天数
int MonthDays(int year, int month)
{
int months[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
if (YearDays(year) == 366) { //如果该年是闰年,则2月份为29天
months[2] = 29;
}
return months[month];
}
//获取星期几字符串信息
void GetWeekdayInfo(int n, char *weekday)
{
char weekdays[][STR_LEN] = {"Saturday", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday"};
int index = n % 7;
strncat(weekday, weekdays[index], STR_LEN);
}
//计算n天后的年月日星期信息
void CalDateInfo(int n, int *year, int *month, int *day, char *weekday)
{
GetWeekdayInfo(n, weekday);
*year = 2000;
while (n >= YearDays(*year)) {
n -= YearDays(*year);
(*year)++;
}
*month = 1;
while (n >= MonthDays(*year, *month)) {
n -= MonthDays(*year, *month);
(*month)++;
}
*day = n + 1; //加1是因为每月的第一天是从1号开始的
}
int main()
{
int n;
int year, month, day;
char weekday[STR_LEN] = {0};
while (scanf("%d", &n) != EOF) {
CalDateInfo(n, &year, &month, &day, weekday);
printf("%d-%d-%d %s\n", year, month, day, weekday);
}
return 0;
}
第四题
题目描述:输入一个年月日星期几,计算N天后是哪年哪月哪日星期几,考虑平闰年及各种输入错误情况。
#include <stdio.h>
typedef struct {
int year;
int month;
int day;
} Date;
char *g_week[] = {"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};
int g_months[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int IsLeapYear(int year);
void ListDate(int weekday, Date now, int diff);
/* 知道今天星期几以及年月日,编写C程序,要求能算出任意天后是星期几以及年月日 */
void main()
{
int weekday;
Date now;
int diff;
printf("请输入今天是星期几以及日期");
printf("星期几(0..6,星期日..星期六):");
scanf("%d", &weekday);
printf("日期(yyyy-mm-dd): ");
scanf("%d-%d-%d", &now.year, &now.month, &now.day);
printf("相隔天数:");
scanf("%d", &diff);
ListDate(weekday, now, diff);
}
/* 判断闰年 */
int IsLeapYear(int year)
{
return ((year%400==0) || (year%4==0 && year%100!=0)) ? 1 : 0;
}
/* 已知今天是星期几(weekday,0..6,Sunday..Saturday)以及日期(now),输出diff天后是星期几以及日期 */
/* diff > 0 指diff天后,diff < 0 指diff天前 */
void ListDate(int weekday, Date now, int diff)
{
int w1;
Date d1;
/* 计算diff天后是星期几 */
w1 = weekday + diff;
while(w1 < 0)
{
w1 += 7;
}
w1 = w1 % 7;
printf("%d 天后:\n", diff);
printf("%s\n", g_week[w1]);
/* 计算diff天的日期 */
d1.year = now.year;
d1.month = now.month;
d1.day = now.day + diff;
if(d1.day > 0)
{
while(d1.day > g_months[d1.month])
{
d1.day -= g_months[d1.month] + (d1.month==2 && IsLeapYear(d1.year));
d1.month++;
if(d1.month > 12)
{
d1.month = 1;
d1.year++;
}
}
}
else if(d1.day < 0)
{
while(d1.day <= 0)
{
d1.month--;
if(d1.month <= 0)
{
d1.month = 12;
d1.year--;
}
d1.day += g_months[d1.month] + (d1.month==2 && IsLeapYear(d1.year));
}
}
printf("%d-%d-%d\n", d1.year, d1.month, d1.day);
}
第五题
题目描述:设计一个表示日期的结构体。编写一个函数,计算两个日期之间差多少天。在 main 函数 中调用该函数,并显示。
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define LEAP_YEAR 366
#define COMMON_YEAR 365
int g_months[]={0,31,28,31,30,31,30,31,31,30,31,30,31};
typedef struct {
int year;
int month;
int day;
} Date;
typedef struct date DATE;
void interval_days()
{
int i,result,sum1,sum2;
Date date1, date2;
printf("请输入第一个日期: ");
scanf("%d-%d-%d", &date1.year, &date1.month, &date1.day);
if(date1.year<=0 || date1.month<=0 || date1.month>12 || date1.day<=0 || date1.day>31)
{
printf("输入错误,请准确输入日期!\n");
exit(-1);
}
printf("请输入第二个日期: ");
scanf("%d-%d-%d",&date2.year,&date2.month,&date2.day);
if(date2.year<0 || date2.month<0 || date2.month>12 || date2.day<0 || date2.day>31)
{
printf("输入错误,请准确输入日期!\n");
exit(-1);
}
//算法思路:我们以公元1年1月1日为基准,分别计算间隔天数,然后两者相减就是这两个日期的间隔天数了
sum1=sum_days(&date1);
sum2=sum_days(&date2);
result=abs(sum1-sum2);
printf("日期之差为: %d\n",result);
}
int sum_days(DATE *date)
{
int i,sum;
//计算公元1年1月1日到某年的1月1号的天数
for(i=1,sum=0;i<date->year;i++){
if(i%400==0 || (i%4==0 && i%100!=0))
sum+=LEAP_YEAR;
else
sum+=COMMON_YEAR;
}
//计算该年的1月1号到该日期的天数
for(i=1;i<date->month;i++){
sum+=g_months[i];
}
if(date->month>2 && (date->year%400==0 || (date->year%4==0 && date->year%100!=0)))
sum+=date->day+1;
else
sum+=date->day;
return sum;
}
int main()
{
interval_days();
return 0;
}