蓝桥杯24.A:日期统计(C++)

蓝桥杯编程竞赛:数学算法与日期统计的C语言实现
文章讲述了蓝桥杯竞赛中数学算法题目与程序设计部分,涉及填空题和程序题的解题策略,重点介绍了如何使用C语言实现日期统计,包括穷举法、数组操作和日期有效性判断。

蓝桥杯题目

题目风格大致分为两类

  1. 数学
  2. 算法 -> 程序
    题目设置
    十道题
    填空题两道,5分
    程序设计题两道,10分
    程序设计题两道,15分
    程序设计题两道,20分
    程序设计题两道,25分

试题A

在这里插入图片描述

  1. 这是一道结果填空题,只需要写结果就行
  2. 如出现时间限制,内存限制,为程序设计题,需要写程序
  • 思路分析
  1. 先从数组首位开始依次找,直到依次找出2023,然后在2023的最后的3之前的数组的内容就不需要计入统计了,直接从3之后的内容开始纳入统计,计算出适合月份和天数的情况(1.1——12.31)包含有多少种。
  2. 先完成一趟的情况,再往里面套(数九、素数、冒泡、排序)
  3. 结果是235
    注意
  4. 只需要讨论不同的情况
    程序
  • 填空题三步
  1. 运算/程序
    1. 填空题超过3分钟计算不出来,循环超过3层,或超过30次,考虑用程序
  2. 数据存储
    1. 数据结构 -> 数组
      只需要存放2023中的3之后的内容
  3. 程序设计
    1. 算法思想 -> 穷举法
      1. 通过分析,月份的十位要不是0要不是1
        代码示范1
/*日期统计 - 纯C */  
#include <stdio.h>
#define N 41  
  
// 判断日期是否存在  
int isExist(int buff2[], int date)  
{  
    for(int i = 0; i < 366; i++)  
    {  
        if(buff2[i] == date) 
	    return 1;  
    }  
  
    return 0;  
}  
  
int main()  
{  
    int cnt = 0;  //设置计数器
	int buff2[366] = {0}; // 存放日期  
	int buff[N] = { 3,8,5,1,6,3,4,6,7,0,  
					7,8,2,7,6,8,9,5,6,5,  
					6,1,4,0,1,0,0,9,4,8,  
					0,9,1,2,8,5,0,2,5,3,3 };  
					//将需要的数据存放在数组中
  
for(int y1 = 0; y1 < N; y1++)  //遍历数组中的数据,确定月份第一个数
{  
	if(buff[y1] == 0 || buff[y1] == 1)  //如果第一个数为0/1,进入内循环
	{  
		for(int y2 = y1+1; y2 < N; y2++)  //从下一个开始遍历第二个数,月份的第二位
		{  
			int yue = buff[y1]*10 + buff[y2];  //计算月份
			if(yue >= 1 && yue <= 12)  //月份大于0,小于13
			{  
				for(int d1 = y2+1; d1 < N; d1++)  //往后遍历日期的第一位
				{  
					for(int d2 = d1+1; d2 < N; d2++)  //往后遍历日期的第二位
					{  
						int day = buff[d1]*10 + buff[d2];  //计算日期
						int date = yue*100 + day;  //计算总日期
  
						if((yue == 2) && (day >=1 && day <= 28))  //如果月份等于2的话,日期大于1小于28,2023不是闰年
						{  
							if(isExist(buff2, date) == 0)
							{  
								buff2[cnt++] = date;  //满足条件,将日期存入数组
							}  
						}else if(((yue == 1) || (yue == 3) ||(yue == 5)  
							|| (yue == 7) || (yue == 8) || (yue == 10)  
							|| (yue == 12)) && (day >=1 && day <= 31))  //如果月份是135781012,日期大于1小于31
							{  
								if(isExist(buff2, date) == 0)  
								{  
									buff2[cnt++] = date;  //满足条件,将日期存入数组
								}  
							}else if(((yue == 4) || (yue == 6) ||(yue == 9)  
							|| (yue == 11)) && (day >=1 && day <= 30))  //如果月份是46911,日期大于1小于30
							{  
								if(isExist(buff2, date) == 0)  
								{  
									buff2[cnt++] = date;  //满足条件,将日期存入数组
								}  
							}  
						}  
					}  
				}  
			}  
		}  
	}  
  
	printf("%d\n", cnt);  //输出个数
	return 0;  
}

代码示范2

  • 混入C++代码
/*日期统计 - C/C++混编 */ 
#include <stdio.h> // 包含标准输入输出库 
#include <iostream> // 包含C++输入输出流库 
#include <set> // 包含C++标准库中的set容器,用于存储唯一的日期 using namespace std; // 使用C++标准库的命名空间 
#define N 41 // 定义常量N为41,表示缓冲区的大小 
int main() 
{ 
	set<int> dates; // 声明一个set容器,用于存储唯一的日期 
	int buff[N] = { 
	// 声明并初始化一个大小为N的整型数组,存储日期的数字表示 
		3, 8, 5, 1, 6, 3, 4, 6, 7, 0, 
		7, 8, 2, 7, 6, 8, 9, 5, 6, 5, 
		6, 1, 4, 0, 1, 0, 0, 9, 4, 8, 
		0, 9, 1, 2, 8, 5, 0, 2, 5, 3, 3 }; 
	// 遍历日期数组,寻找有效日期 
	for(int y1 = 0; y1 < N; y1++) 
	{ 
		// 如果日期的十位或个位为0或1,则可能为月份的十位或个位 
		if(buff[y1] == 0 || buff[y1] == 1) 
		{ 
			// 遍历寻找可能的月份的个位 
			for(int y2 = y1 + 1; y2 < N; y2++) 
			{ 
				int yue = buff[y1] * 10 + buff[y2]; // 计算月份 
				// 如果月份有效 
				if(yue >= 1 && yue <= 12) 
				{ 
					// 遍历寻找可能的日期的十位和个位 
					for(int d1 = y2 + 1; d1 < N; d1++) 
					{ 
						for(int d2 = d1 + 1; d2 < N; d2++) 
						{ 
							int day = buff[d1] * 10 + buff[d2]; 
							// 计算日期 
							int date = yue * 100 + day; 
							//将月份和日期组合成一个整数表示的日期 
							
							// 判断日期是否合法并添加到set容器中 
							if((yue == 2) && (day >= 1 && day <= 28)) 
							{ 
								dates.insert(date); 
							} 
							else if(((yue == 1) || (yue == 3) || (yue == 5) 
							|| (yue == 7) || (yue == 8) || (yue == 10) 
							|| (yue == 12)) && (day >= 1 && day <= 31)) 
							{ 
								dates.insert(date); 
							} 
							else if(((yue == 4) || (yue == 6) || (yue == 9) 
							|| (yue == 11)) && (day >= 1 && day <= 30)) 
							{ 
								dates.insert(date); 
							} 
						} 
					} 
				} 
			} 
		} 
	} 
	
	printf("%d\n", dates.size()); // 打印set容器中日期的数量 
	return 0; 
}
### 关于蓝桥杯 C++ 日期统计的解题方法 在解决蓝桥杯中的日期统计问题时,通常需要考虑以下几个方面: #### 1. **日期合法性验证** 为了确保输入的数值能够表示一个合法的日期,程序需完成以下任务: - 验证月份是否有效(即范围应在1到12之间)。 - 对每个月份对应的天数进行校验,特别注意闰年的影响。例如,二月在平年有28天,在闰年则有29天。 可以通过如下逻辑来判断某一年是否为闰年[^2]: ```cpp bool isLeapYear(int year) { return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0); } ``` #### 2. **回文日期检测** 对于涉及回文日期的问题,可以采用字符串反转的方法来检查给定日期是否满足回文特性。具体做法是从左向右读取与从右向左读取的结果一致即可认为是回文日期[^4]。 下面提供一段简单的代码片段用于判定某个特定格式下的日期是否构成回文结构: ```cpp #include <string> using namespace std; // 判断是否为回文串 bool isPalindrome(const string& dateStr){ int len = dateStr.length(); for(int i=0;i<len/2;i++){ if(dateStr[i]!=dateStr[len-i-1]){ return false; } } return true; } void checkDateAsPalindrome(){ // 假设我们有一个标准形式 YYYYMMDD 的日期字符串 string testDate="20211202"; bool result=isPalindrome(testDate); cout << (result?"Yes":"No")<<endl; } ``` #### 3. **寻找下一个符合条件的日期** 一旦确认当前日期不符合条件,则需要继续搜索后续可能存在的目标日期。这一步骤往往依赖递增的方式逐一尝试直到找到为止。 完整的解决方案框架可设计成这样: ```cpp #include <iostream> #include <sstream> using namespace std; struct Date{ int y,m,d; }; // 辅助函数:将日期转为易于比较的形式 int convertToDateNumber(Date dt){ return dt.y*10000 + dt.m*100 +dt.d ; } // 主要功能模块:获取下一天的具体情况 Date getNextDay(Date today){ static const int daysInMonth[] ={0,31,(isLeapYear(today.y)?29:28),31, 30,31,30,31,31,30,31,30,31}; Date tomorrow=today; ++tomorrow.d; if(tomorrow.d>daysInMonth[tomorrow.m]){ tomorrow.d=1; ++tomorrow.m; if(tomorrow.m>12){ tomorrow.m=1; ++tomorrow.y; } } return tomorrow; } // 查找第一个匹配指定属性的新日期 Date findNextSpecialDate(Date start,int (*predicate)(const Date&)){ while(! predicate(start))start=getNextDay(start); return start; } // 自定义谓词 - 这里假设我们要找的是回文日期 bool isPalindromicDate(const Date &dt){ ostringstream oss; oss.fill('0'); oss.width(4);oss<<dt.y; oss.width(2);oss<<dt.m; oss.width(2);oss<<dt.d; string s=oss.str(); size_t half=s.size()/2; for(size_t i=0;i<half;++i){ if(s[i]!=s[s.size()-i-1])return false; } return true; } int main(){ Date initial={2021,12,2}; // 可替换为你感兴趣的起始点 Date next=findNextSpecialDate(initial,isPalindromicDate); cout<<"The Next Palindrome Date Is:"<<next.y<<"/"<<next.m<<"/"<<next.d<<'\n'; } ``` 上述代码实现了基本的功能需求,并且具备一定的扩展性以便适应更多复杂场景的要求。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值