唤我沈七就好啦。
日期类问题可以说是蓝桥杯当中的常客了,
我整理了一下历年真题,归纳出了其中的模板。
希望对你有所帮助。
#include
using namespace std;
int sum;
int m[13]={0,31,29,31,30,31,30,31,31,30,31,30,31};//枚举月份
int main()
{
int a,b,x;
cin>>a>>b;
for (int i = 1; i <13; i ++ )//月
for(int j=1;j<=m[i];j++)//日
{
//月份和日期确定下来之后,回文日期的年份也就确定下来了
x=(j%10*1000+j/10*100+i%10*10+i/10)*10000+i*100+j;
if(x>=a&&x<=b)//判断是否在给定区间内
sum++;
}
cout<<sum;
return 0;
}
int day[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
bool check(int y ,int m , int d)
{
if(!d||!m||m>12)return 0;
if(m!=2)
{
if(d>day[m])
return 0;
}
else
{
int idx=((y % 100!=0 && y % 4==0)||(y%400==0));
if(d>day[2]+idx)return 0;
}
return 1;
}
int moth[13]= {0,31,28,31,30,31,30,31,31,30,31,30,31};
int get(int y, int m)
{
int leap = y%4==0&&y%100!=0||y%400==0;
if(m!=2)
return moth[m];
return 28+leap;
}
#include
using namespace std;
int moth[13]= {0,31,28,31,30,31,30,31,31,30,31,30,31};
int get(int y, int m)
{
int leap = y%4==0&&y%100!=0||y%400==0;
if(m!=2)
return moth[m];
return 28+leap;
}
int main()
{
int ans=0;
int y,m,d;
int y1,m1,d1;
cin>>y>>m>>d;
cin>>y1>>m1>>d1;
while(1)
{
ans++,d++;
if(d>get(y,m))
m++,d=1;
if(m>12)
y++,m=1;
if(y==y1&&m==m1&&d==d1)
{
cout<<ans;
return 0;
}
}
return 0;
}
1.先计算出两日期的相隔天数
2.由当天的日期星期反推给定日期的星期
(day 1 = day 2 - 相隔天数 % 7 )
3.根据给定日期的星期与所取星期的关系,判断答案与 相隔天数 / 7 是否差 1
注:Excel 只能计算1900年后的时间
#include
using namespace std;
int moth[13]= {0,31,28,31,30,31,30,31,31,30,31,30,31};
int get(int y, int m)
{
int leap = y%4==0&&y%100!=0||y%400==0;
if(m!=2)
return moth[m];
return 28+leap;
}
int main()
{
int y,m,d,n;
cin>>y>>m>>d>>n;
while(n--)
{
d++;
if(d>get(y,m))
m++,d=1;
if(m>12)
y++,m=1;
}
printf("%d年%d月%d日",y,m,d);
return 0;
}
第四届蓝桥杯C++组
大数学家高斯有个好习惯:无论如何都要记日记。
他的日记有个与众不同的地方,他从不注明年月日,而是用一个整数代替,比如:4210
后来人们知道,那个整数就是日期,它表示那一天是高斯出生后的第几天。这或许也是个好习惯,它时时刻刻提醒着主人:日子又过去一天,还有多少时光可以用于浪费呢?
高斯出生于:1777年4月30日。
在高斯发现的一个重要定理的日记上标注着:5343,因此可算出那天是:1791年12月15日。
高斯获得博士学位的那天日记上标着:8113
请你算出高斯获得博士学位的年月日。
坑点:
这题不能用Excel,不符合适用范围
根据上面模板算出时间后需要 - 1!!!
这计算的是相隔的天数 需要减去 1777年4月30日,他出生的那一天!!
#include
using namespace std;
int moth[13]= {0,31,28,31,30,31,30,31,31,30,31,30,31};
int get(int y, int m)
{
int leap = y%4==0&&y%100!=0||y%400==0;
if(m!=2)
return moth[m];
return 28+leap;
}
int main()
{
int y,m,d,n;
cin>>y>>m>>d>>n;
while(n--)
{
d++;
if(d>get(y,m))
m++,d=1;
if(m>12)
y++,m=1;
}
printf("%d年%d月%d日",y,m,d-1);
//一定要 - 1!!!,因为这计算出来的是相隔的天数 需要减去 1777年4月30日,他出生的那一天!!
return 0;
}
第八届蓝桥杯省赛C++组
小明正在整理一批历史文献。这些历史文献中出现了很多日期。
小明知道这些日期都在1960年1月1日至2059年12月31日。
令小明头疼的是,这些日期采用的格式非常不统一,有采用年/月/日的,有采用月/日/年的,还有采用日/月/年的。
更加麻烦的是,年份也都省略了前两位,使得文献上的一个日期,存在很多可能的日期与其对应。
比如02/03/04,可能是2002年03月04日、2004年02月03日或2004年03月02日。
给出一个文献上的日期,你能帮助小明判断有哪些可能的日期对其对应吗?
【 输入格式】
一个日期,格式是”AA/BB/CC”。
即每个’/’隔开的部分由两个 0-9 之间的数字(不一定相同)组成。
【输出格式】
输出若干个不相同的日期,每个日期一行,格式是”yyyy-MM-dd”。
多个日期按从早到晚排列。
【 数据范围】
0≤A,B,C≤9
【输入样例】:
02/03/04
【输出样例】:
2002-03-04
2004-02-03
2004-03-02
#include
using namespace std;
int day[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
bool check(int y ,int m , int d)
{
if(!d||!m||m>12)return 0;
if(m!=2)
{
if(d>day[m])return 0;
}
else
{
int idx=((y % 100!=0 && y % 4==0)||(y%400==0));
if(d>day[2]+idx)return 0;
}
return 1;
}
int main()
{
int a,b,c;
scanf("%d/%d/%d",&a,&b,&c);
for(int i = 19600101 ; i <= 20591231 ; i ++)
{
int y=i/10000,m=i%1000/100,d=i%100;
if(check(y,m,d))
{
if((y%100==a&&m==b&&d==c)|| //年月日
(y%100==c&&m==a&&d==b)|| //
(y%100==c&&m==b&&d==a))
printf("%d-%02d-%02d\n",y,m,d);//补前导
}
}
return 0;
}
第一届蓝桥杯C/C++组
13号又是一个星期五。13号在星期五比在其他日子少吗?为了回答这个问题,请你写一个程序计算每个月的十三号落在周一到周日的次数。
给出N年的一个周期,要求计算1900年1月1日至1900+N-1年12月31日中十三号落在周一到周日的次数,N为正整数且不大于400。
这里有一些你要知道的:
1、1900年1月1日是星期一。
2、4,6,11和9月有30天。其他月份除了2月都有31天。闰年2月有29天,平年2月有28天。
3、年份可以被4整除的为闰年(1992年是闰年,但是1990年不是闰年)。
4、以上规则不适合于世纪年。可以被400整除的世纪年为闰年,否则为平年。所以,1700,1800,1900和2100年是平年,而2000年是闰年。
【输入格式】
一个正整数:N。
【输出格式】
七个在一行且相分开的整数,它们代表13日是星期六、星期日、星期一、…、星期五的次数。
【输入样例】
20
【输出样例】
36 33 34 33 35 35 34
#include
using namespace std;
long long ans=1,cnt[100];
int moth[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int get(int y,int m)
{
if(m!=2)
return moth[m];
int leap=y%4==0&&y%100!=0||y%400==0;
return 28+leap;
}
int main()
{
int n;
cin>>n;n=n+1900-1;
int y=1900,m=1,d=1;
while(1)
{
d++;
ans++;
int day = ans%7;
if(d>get(y,m))
m++,d=1;
if(m>12)
y++,m=1;
if(d==13)
cnt[day]++;
if(y==n&&m==12&&d==31)
{
break;
}
}
cout<<cnt[6]<<" "<<cnt[0]<<" ";//注意输出顺序,这是个坑
for(int i = 1 ; i <= 5 ; i ++)
cout<<cnt[i]<<" ";
return 0;
}
ok以上就是对 蓝桥杯日期类模板 的全部讲解啦,很感谢你能看到这儿。如果有遗漏、错误或者有更加通俗易懂的讲解,欢迎小伙伴私信我,我后期再补充完善。
https://www.acwing.com/activity/content/19/
https://blog.csdn.net/xiao_cangtian/article/details