【练习题+1】某人三天打渔两天晒网,假设他从1990年1月1日开始打渔三天,然后晒网两天,请编程回答任意的一天他在打渔还是晒网。

刚刚开始学习,在题库里面抽到这一题。

某人三天打渔两天晒网,假设他从1990年1月1日开始打渔三天,然后晒网两天,请编程回答任意的一天他在打渔还是晒网。
一个男孩工作3天,而请假2天。如果他在1990年1月1日工作,那么对于通过键盘输入的日期,请编写一个程序来确定男孩在做什么,工作或休息?
输入和输出示例:
1)输入
1990-01-05
输出:
他正在休息。
2)输入:
1990-01-07
输出:
他正在工作。
3)输入:
1990-01-33
输出:
输入无效。
输入数据格式:“%4d-%2d-%2d”
输出数据格式:“输入无效。”或“他正在休息。” 或“他正在工作。”

1. 闰年的表达式,刚开始我写错了,没有想到整百年份的问题,正确表达(year%4000)||(year%100!=0&&year%40);****
2. 对于已知年份求日期,开始我用了三个for循环,穷举每天日期再判断是否合法,计数,效率实在太低,最后,使用一个for求整年天数,闰年366,平年365,
使用数组存储月份天数,另起一个for求月份天数,最后再加上天数减一,嗯哼?????,这个地方好像还有点问题,到底为什么减一呢?????还是有点迷啊
轻轻松松就被绕晕了。
~


  1. 闰年的判别表达式: 四位年份,闰年满足以下条件,后两位被 4整除 或者前两位被 4整除 简单说,就是,被 400 整除的年 或 被 4 整除但 不被 100 整除的年
(year % 400) || (year % 100  != 0 && year % 400 != 0  )

其他的代码注释里都有
代码如下:

#include <stdio.h>


int main(){

    
    int m_days[13] ={0,31,28,31,30,31,30,31,31,30,31,30,31};	
    int year, month, day, sumdays = 0;

    scanf("%4d-%2d-%2d", &year, &month, &day);
    // 检测非法输入
    if (year < 1990 
    || month < 1 
    || month > 12 
    || day < 1 
    || day > m_days[month])
     {
        printf("输入无效。\n");
        return 0;
     }

    // 加上 每年的基本天数
    sumdays += (year - 1990) * 365;

    // 计算有多少个闰年 就额外加多少天
    // 1992 年是闰年,每过四年是一个闰年
    sumdays += ( (year - 1990) / 4 );

    // 累加每月天数,其实,数组可以存成 {0 , 31, 59, 90 .....} 这样免去累加
    for (int i = 1; i < month; i++){
        sumdays += m_days[i];
    }

    // 加上这个月的天数
    sumdays += day;

    // 根据算法: 输入 1990-1-5 ,计算得 sumdays = 5
    // 所以 1 2 3 4 5 日
    // 在 sumdays - 1 整除 5 的余数 分别为 0 1 2 3 4
    // 那么休息的条件就是 >= 3
    // 如果 sumdays 不减一 整除 5 的余数 分别为 1 2 3 4 0
    // 休息的条件是 > 3 || == 0
    if ( ((sumdays - 1) % 5) >= 3){
        printf("他正在休息。\n");
    }else{
        printf("他正在工作。\n");
    }
    return 0;
}

下面是烂代码

#include <stdio.h>
#include <stdlib.h>

 int main() 

{
	while(1){	 //这个while是为了方便多次测试

	int pastday=0,mday=0;
	while(1)
	{
	int year=1990,month=-1,day=-1,verbool=0;		//初始化很重要,这样可以避免输入不全出错 
	scanf("%4d-%2d-%2d",&year,&month,&day);
	getchar();
	verbool = verData(year,month,day);
	if (verbool==1)break;
	}

	printf("你输入的日期是%d年%d月%d日\n",year,month,day);
	pastday=caData(year,month,day);
	printf("据1990-01-01过了%d天",pastday);
	mday=pastday%5;
	if(mday<3&&mday>=0)
	printf("\n今天他打鱼\n");
	else
	printf("\n今天他晒网\n"); 
		
	}
return 0;
}

//检测输入日期是否合法 
int verData(int verY,int verM,int verD)
	{
	int days[13] ={0,31,28,31,30,31,30,31,31,30,31,30,31};			//好像并不需要12月的天数 
	if(verY<1990||verM<1||verM>12||verD>=days[verM])
		{
		printf("输入有误,请重新输入:\n");
		return 0;
		}
	else
		{

		return 1;
		}
	}
	
	//计算天数
	
	
	int  caData (int caY,int caM,int caD)
	{
		int i=0,k=1;
		int year=0;
		int days[13] ={0,31,28,31,30,31,30,31,31,30,31,30,31};
	//计算1990年1月1日到指定年份的1月1日天数		
		for (year=1990;year<caY;year++) 
		{
			if((year%400==0)||(year%100!=0&&year%4==0))//闰年 
			{
				i+=366;
		 	}else{
			 	i+=365;
		 	 }
		}
	//计算指定年份日期到当年1-1天数
	//月份天数 
		for(k=1;k<caM;k++)
		{
			if((year%400==0)||(year%100!=0&&year%4==0)&&(k=2))
			i+=29;
			else{
			i+=days[k];
			}
		}	
		i+=caD-1;
		return i;
		
		
	
	}
//*************************************************************************************************************************************	
//*************************************************************************************************************************************
//失败品,失败品,失败品,失败品 

//检测输入日期是否合法 
//int verData(int verY,int verM,int verD)
//	{
//		if (verY<1990||verM<1||verM>12||verD<1||verD>31)//取值范围 
//		return 0; 
//		else if((verY%400==0)||(verY%100!=0&&verY%4==0)&&verM==2&&verD>29)//润年2月取值 
//		return 0;
//		else if(verY%4!=0&&verM==2&&verD>28) // 平年二月取值 
//		return 0;
//		else if (verY%4!=0&&verM<7&&verM%2==0&&verD>30)//是否31日 
//		return 0;
//		else if(verY%4!=0&&verM>7&&verM%2!=0&&verD>30)//是否31日 
//		return 0;
//		else
//		return 1;
//		 
//	}
//	
//	int    caData (int caY,int caM,int caD)
//	{
//		int i=0;
//		int year=0,month=0,day=0;
//计算1990年1月1日到指定年份的1月1日天数		
//	for (year=1990;year<caY;year++) 
//	{
//		for(month=1;month<12;month++)
//		{
//			for(day=1;day<31;day++)
//			{
//					if (year%400==0year%4==0&&month==2&&day>29)//润年2月取值 
//						;
//						else if(year%4!=0&&month==2&&day>28) // 平年二月取值 
//						;
//						else if (year%4!=0&&month<7&&month%2==0&&day>30)//是否31日 
//						;
//						else if(year%4!=0&&month>7&&month%2!=0&&day>30)//是否31日 
//						;
//						else
//						i++;
//			}
//		}
//	}
//	
//	//计算指定年份日期到当年1-1天数
//	 
//		return i;
//	}
//	
  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值