星系炸弹(蓝桥杯2015年第六届省赛C/C++ B组第2题)

题目:

在x星系的广袤空间中漂浮着许多x行人造“炸弹”,用来作为宇宙中的路标。每个炸弹都可以设定多少天之后爆炸。
比如:阿尔法炸弹2015年1月1日放置,定时为15天,则它在2015年1月16日爆炸。有一个贝塔炸弹,2014年11月9日放置,定时为1000天,请你计算它爆炸的准确日期。
请填写该日期,格式为yyyy-mm-dd,即4位年份2位日期。比如:2015-02-19
请严格按照格式书写。不能出现其它文字或符号。
[答案]2017-08-05


代码:


#include<stdio.h>
int main()
{
	int year = 2014;//年初始值
	int month = 11;//月
	int date = 9;//日
	int day =1000;//炸弹定时天数
	int days[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };//存放每月对应的天数
	while (day > 0)
	{
		if(month == 0)//判断是否为二月再在判断闰年
		{ 
			if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0)//判断闰年
			{
				days[month] = 29;
			}
			else
				days[month] = 28;
		}

		if (day >= days[month])
		{
			day = day - days[month];//过完一个月份定时相应减去这个月份的天数
			month++;
		}
		else
		{
			date = date + day;
			day = 0;
		}

		if (month > 12)//当月份大于12月,说明过完一年,从下一年的一月开始
		{
			year++;
			month = 1;
		}
	}
	if (date > days[month])
	{
	
		date = date - days[month];
		date--;
		month++;
		if (month > 12)//当月份大于12月,说明过完一年,从下一年的一月开始
		{
			year++;
			month = 1;
		}
	}
	printf("%04d - %02d - %02d", year, month, date);
	//%04d表示不满4位左边补零 ,%02d表示不满2位左边补零
	return 0;
}

运行结果:

在这里插入图片描述


上面是这道题的最终结果,有问题可以在评论区告诉我谢谢了!
下面来分享我做这道题的思路。

1.分析题目

根据题目可知:需要算出2014年11月9日放置的炸弹,在1000天后的爆炸日期
打印格式为yyyy-mm-dd
所以先定义变量年月日,定时的天数

#include<stdio.h>
int main()
{
	int year = 2014;//年初始值
	int month = 11;//月
	int date = 9;//日
	int day = 1000;//炸弹定时天数
	return 0;
}

2.怎么编写代码

我知道了题目的要求需要算出正确答案只需要让炸弹定时的天数一天天过去直到为0时停止,想了下需要用循环来让天数为0停止运行然后打印日期。

#include<stdio.h>
int main()
{
	int year = 2014;//年初始值
	int month = 11;//月
	int date = 9;//日
	int day = 1000;//炸弹定时天数
	while (day > 0)
	{

	}
	printf("%d - %d - %d", year, month, date);

现在不清楚循环里面的循环体怎么去写,但可以确定的是我的打印日期是肯定有问题的,当月份和天数不满两位时要补0,当年分不满四位时需要补0.
比如 0144 - 07 - 01,表示的是114年7月1日
下面就需要调整代码,解决已经发现的问题再去处理未知问题

#include<stdio.h>
int main()
{
	int year = 2014;//年初始值
	int month = 11;//月
	int date = 9;//日
	int day = 1000;//炸弹定时天数
	while (day > 0)
	{

	}
	printf("%04d - %02d - %02d", year, month, date);
	//%04d表示不满4位左边补零 ,%02d表示不满2位左边补零
	return 0;
}

编好后把循环代码屏蔽掉来检查一下打印日期是否正确
用//可以屏蔽后面一行的内容不参与运算
用/**/可以屏蔽中间多行的内容,但不能嵌套使用

#include<stdio.h>
int main()
{
	int year = 2014;//年初始值
	int month = 11;//月
	int date = 9;//日
	int day = 1000;//炸弹定时天数
	/*while (day > 0)
	{

	}*/
	printf("%04d - %02d - %02d", year, month, date);
	//%04d表示不满4位左边补零 ,%02d表示不满2位左边补零
	return 0;
}

测试结果

在这里插入图片描述

看图片中的09就可以说明代码为问题
接下来解决中间的计算问题,可以分析出来每过一个月定时就减去这个月的天数
每个月的天数不一样
1、3、5、7、8 、10 、12 月,这些月份每月有31天
4、6、9 、11月,这些月份有30天
2月要考虑润年和平年,当是闰年是有29天,平年是有28天
如何判断是否是闰年需要看年份,有两种判断方法
1.当年份被4整除且不能被100整除的
2.当年份被400整除
需要定义一个数组来存放每个月对应的天数

3.开始按照上面的思路来编写代码

#include<stdio.h>
int main()
{
	int year = 2014;//年初始值
	int month = 11;//月
	int date = 9;//日
	int day = 1000;//炸弹定时天数
	int days[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };//存放每月对应的天数

	if (day >= 1)
	{
		day--;//把9日这天过完
	}
	if (day >= 21)//现在是9日要过21天才能到下一月的1日
	{
		date = 1;
		day = day - 21;
		month = 12;//重置从1日开始算有利于后面代码的逻辑
	}

	while (day > 0)
	{
		if(month == 0)//判断是否为二月再在判断闰年
		{ 
			if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0)//判断闰年
			{
				days[month] = 29;
			}
			else
				days[month] = 28;
		}

		if (day >= days[month])
		{
			day = day - days[month];//过完一个月份定时相应减去这个月份的天数
			month++;
		}
		else
		{
			date = date + day;
			day = 0;
		}

		if (month > 12)//当月份大于12月,说明过完一年,从下一年的一月开始
		{
			year++;
			month = 1;
		}
	}
	printf("%04d - %02d - %02d", year, month, date);
	//%04d表示不满4位左边补零 ,%02d表示不满2位左边补零
	return 0;
}

代码边玩看下运行结果:

在这里插入图片描述

看结果与答案相比多了一天,接下来找问题
通过尝试其他例子发现不用一开始减一天,而且我重置从下一月的1日开始算,这一月的1日并没有开始过
修改代码:

#include<stdio.h>
int main()
{
	int year = 2014;//年初始值
	int month = 11;//月
	int date = 9;//日
	int day =1000;//炸弹定时天数
	int days[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };//存放每月对应的天数

	//if (day >= 22)//现在是9日要过22天才能到下一月的1日
	//{
	//	date = 1;//这一日买没过完
	//	if (day > 1)
	//	{
	//		day--;
	//	}
	//	day = day - 22;
	//	month = 12;//重置从1日开始算有利于后面代码的逻辑
	//}

	while (day > 0)
	{
		if(month == 0)//判断是否为二月再在判断闰年
		{ 
			if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0)//判断闰年
			{
				days[month] = 29;
			}
			else
				days[month] = 28;
		}

		if (day >= days[month])
		{
			day = day - days[month];//过完一个月份定时相应减去这个月份的天数
			month++;
		}
		else
		{
			date = date + day;
			day = 0;
		}

		if (month > 12)//当月份大于12月,说明过完一年,从下一年的一月开始
		{
			year++;
			month = 1;
		}
	}
	if (date > days[month])
	{
	
		date = date - days[month];
		date--;
		month++;
		if (month > 12)//当月份大于12月,说明过完一年,从下一年的一月开始
		{
			year++;
			month = 1;
		}
	}
	printf("%04d - %02d - %02d", year, month, date);
	//%04d表示不满4位左边补零 ,%02d表示不满2位左边补零
	return 0;
}
  • 29
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值