目录
题目:
题目描述:
题目链接:
思路:
自己的思路详解:
更好的思路详解:
代码:
自己的思路代码详解:
更好的思路代码详解:
题目:
题目描述:
题目链接:
P10575 [蓝桥杯 2024 国 A] 下一次相遇 - 洛谷
下一次相遇 - 蓝桥云课
思路:
自己的思路详解:
我一开始自己的思路就是直接暴力遍历,关于日期问题的遍历其实多写几次就会发现格式都差不多(后续有时间我会总结蓝桥杯中的日期问题)。日期问题的遍历格式差不多就是全局变量打表定义每月的天数,定义函数判断闰年,三层for循环遍历年月日,其中按照题意对特殊的开始时间与结束时间判断一下即可。这里定义cnt来记录从2024年6月1日过了多少天到今天,cnt%7==0表示恰好过了n周。
这个思路比较暴力,写代码的话也还是比较长的,但是日期问题的遍历格式写熟练了还是挺好想的。
更好的思路详解:
因为这题是填空题,其实只要把逻辑思考明白就能想出答案。我的代码注释已经很详细地把逻辑推导写出来了,跟着代码注释一步步推导即可
代码:
自己的思路代码详解:
#include<bits/stdc++.h> //这题是填空题,答案是2030,这个代码是我自己思考的遍历方式,做法比较暴力
using namespace std; //在看完题解之后,发现其实有更简短的代码,以及更好的思考方式
int cnt; //cnt表示的是从2024年6月1日过了多少天
int daysofmonth[]={0,31,28,31,30,31,30,31,31,30,31,30,31}; //每月的天数,索引为0时空放个0
bool isleaqyear(int y) //定义函数判断闰年
{
if(y%400==0||(y%4==0&&y%100!=0))
{
return true;
}
else
{
return false;
}
}
int main()
{
for(int year=2024;year<=2099;year++) //题目没有明确遍历结束的范围,我们自己先设一个比较大的年
{
int monthmin=1;
if(year==2024) //题目是从2024年6月1号开始
{
monthmin=6;
}
for(int month=monthmin;month<=12;month++)
{
int daymax=daysofmonth[month];
if(isleaqyear(year)==true&&month==2)
{
daymax=29;
}
for(int day=1;day<=daymax;day++)
{
if(month==6&&day==1&&cnt%7==0) //cnt%7==0表示恰好过了n周,即表示某年6月1号是周六
{
if(year!=2024)
{
cout<<year<<endl;
return 0;
}
}
cnt++;
}
}
}
}
更好的思路代码详解:
//这题是填空题,其实甚至不需要写代码,把逻辑思考明白就能想出来
//闰年的判断:能被400整除或能被4整除但是不能被100整除,平年365天,闰年366天,多的一天在二月,2024是闰年
//每年同一天星期数的变化要分为两种情况:第一种是这一天在每年2月28及之前,第二种是在3月1日及以后
//要这样分类讨论就是因为闰年多的那一天是2月29日
//第一种情况:2023.2.1是星期三,问2024.2.1及2025.2.1是星期几?
//2023.2.1到2024.2.1过了一年,虽然2024年是闰年但是过的这一年并没有涉及2月29日,所以这一年过了365天
//即2023.2.1到2024.2.1过了365天,365%7=1,即过了n周多一天,所以2024.2.1星期相比23向后推一天,即星期四
//同理,2024.2.1到2025.2.1过了一年,但是2024是闰年并且这一年涉及2月29日,所以这一年过了366天
//即2024.2.1到2025.2.1过了366天,366%7=2,即过了n周多两天,所以2025.2.1星期相比24向后推两天,即星期六
//第二种情况如题:2024.6.1是星期六,问哪一年的6.1也是星期六?
//2024.6.1到2025.6.1过了一年,虽然2024是闰年但是过的这一年并没有涉及2月29日,所以这一年过了365天
//365%7=1,2025.6.1星期相比2024向后推一天,即星期天
//2025.6.1~2026.6.1,365%7=1,2026.6.1是星期一
//2026.6.1~2027.6.1,365%7=1,2027.6.1是星期二
//2027.6.1~2028.6.1,2028是闰年且涉及2月29日,366%7=2,2028.6.1是星期四
//2028.6.1~2029.6.1,2028是闰年但是不涉及2月29日,365%7=1,2029.6.1是星期五
//2029.6.1~2030.6.1,365%7=1,2030.6.1是星期六
//当然可以用代码实现,显然这比年月日三重for循环遍历的思路简短
#include<bits/stdc++.h>
using namespace std;
int cnt;
bool isleaqyear(int y) //定义函数判断闰年
{
if(y%400==0||(y%4==0&&y%100!=0))
{
return true;
}
else
{
return false;
}
}
int main()
{
for(int year=2025;year<=2099;year++)//从2025开始遍历,结束先设一个比较大的年份,反正找到就退出
{
if(isleaqyear(year)==true) //就是将上面的思路转换为代码(这里涉及2月29日是看后面的年份)
{
cnt+=2; //如果是闰年,相当于星期向后推两天
}
else
{
cnt+=1; //如果是平年,相当于星期向后推一天
}
if(cnt%7==0) //看看向后推了几周余几天,这里表示的是没有余天数,即还是星期六
{
cout<<year<<endl;
return 0; //只要找到第一个成立的年份就退出
}
}
}