目錄
題目:
題目描述:
題目鏈接:
思路:
自己的思路詳解:
更好的思路詳解:
代碼:
自己的思路代碼詳解:
更好的思路代碼詳解:
題目:
題目描述:
題目鏈接:
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; //只要找到第一個成立的年份就退出 }}
}