题解:P12843 [蓝桥杯 2025 国 A] 生日相遇问题
题目传送门
思路
分析
- 需判断每个年份是否为闰年。
- 使用 Zeller 公式计算给定日期的星期几(不懂的请看百度)。
- 特别地,若生日为
2 月29 日,非闰年按2 月28 日计算。
判断闰年
这个都很熟悉,能被
每月的天数
小学就背过,非闰年
根据 Zeller 公式计算星期几
公式为:
其中:
代码
#include<bits/stdc++.h>
#define lcm(x,y) x/__gcd(x,y)*y
#define lb(x) (x&-x)
#define str to_string
using namespace std;
using ll=long long;
const double EPS=1e-6,PAI=acos(-1.0);
const int MAX=3e4+5,mod=1e9+7,MOD=998244353;
bool isLeap(int y){// 判断是否为闰年
return(y%4==0&&y%100!=0)||(y%400==0);
}
vector<int>day(int y){// 获取每月天数
vector<int>d={0,31,28,31,30,31,30,31,31,30,31,30,31};
if(isLeap(y))d[2]=29;
return d;
}
int get(int y,int m,int d){// 计算星期几 (0=星期日)
if(m<3){
m+=12;
y--;
}
int c=y/100;
y%=100;
int w=(c/4-2*c+y+y/4+13*(m+1)/5+d-1)%7;
return(w+7)%7;
}
int m,d1,d2,n,k;
bool f=false;
int main(){
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
cin>>m>>d1>>n>>d2>>k;
for(int y=2025;y<2025+k;y++){
vector<int>days=day(y);
int a1=d1,a2=d2;// 实际日期
// 处理2月29日在非闰年的情况
if(m==2&&d1==29&&!isLeap(y))a1=28;
if(n==2&&d2==29&&!isLeap(y))a2=28;
int w1=get(y,m,a1),w2=get(y,n,a2);
if(w1==w2){
cout<<y<<'\n';
f=true;
}
}
if(!f)cout<<"No Answer\n";
return 0;
}
时间复杂度
应该是
AC 记录