蓝桥2017第八届省赛第七题 日期问题 思路:暴力枚举从1960年1月1日到2059年12月31日的所有合法日期,然后拆分出年月日,如果符合题目中的三种情况之一(年/月/日 月/日/年 日/月/年)的输出即可
#include<bits/stdc++.h>
using namespace std;
int a[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int check(int year, int month, int day) {
if (month == 0 || month > 12) {
return false;
}
if (month != 2) {
if (day > a[month] || day == 0)
return false;
}
if (month == 2) {
if (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)) {
a[month] = 29;
if (day > a[month] || day == 0)
return false;
} else {
a[month] = 28;
if (day > a[month] || day == 0)
return false;
}
}
return true;
}
int main() {
int a, b, c;
scanf("%d/%d/%d", &a, &b, &c);
for (int i = 19600101; i <= 20591231; i++) {
int day = i % 100;
int month = i / 100 % 100;
int year = i / 10000;
bool flag = check(year, month, day);
if (flag) {
int year1 = year % 100;
if ((year1 == a && month == b && day == c) || (year1 == c && month == a && day == b) || (year1 == c && month == b && day == a)) {
printf("%d-%02d-%02d\n", year, month, day);
}
}
}
}
数字拆分出年月日
int year=n/10000;
int month=n/100%100;
int day=n%100;
判断一个拆分出来的年月日是否合法 首先判断月,月份等于0或大于12都是合法的 其次再判断日,这里2月份要分平年与闰年判断,平年28天,闰年29天,其余直接判断即可,如果天数大于当前月份的天数,即为不合法
int check(int year, int month, int day) {
if (month == 0 || month > 12) {
return false;
}
if (month != 2) {
if (day > a[month] || day == 0)
return false;
}
if (month == 2) {
if (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)) {
a[month] = 29;
if (day > a[month] || day == 0)
return false;
} else {
a[month] = 28;
if (day > a[month] || day == 0)
return false;
}
}
return true;
}
蓝桥杯2018第九届省赛第一题 思路:判断一下闰年还是平年,然后手算即可
#include<bits/stdc++.h>
using namespace std;
int main()
{
int year=2020;
if(year%400==0||(year%4==0&&year%100!=0))
{
cout<<"闰年"<<endl;
}
else
{
cout<<"平年"<<endl;
}
cout<<31+29+31+30+4<<endl;
}
蓝桥杯2019第十届省赛第七题 回文日期 错了4次,这要是真放在比赛的时候,就无了 思路:判断n之后的第一个回文日期和第一个ABABBABA型的回文日期,暴力枚举即可,一开始我想的是枚举n-89991231,然后去判断就好了,由于只有8位,直接可以把每一位存到一个数组里,这时候就可以直接去判断数组 回文:a[0] == a[7] && a[1] == a[6] && a[2] == a[5] && a[3] == a[4] ABABBABA型回文:(a[0] == a[2]) && (a[2] == a[5]) && (a[5] == a[7]) && (a[1] == a[3]) && (a[3] == a[4]) && (a[4] == a[6]) 这是我一开始的写法,可以发现是错的,因为忽略了A不等于B的条件,11111111也是符合上述的判断,但是并不符合题意 所以我们还得限制A不等于B 正确的写法应该是:(a[0] != a[1]) && (a[0] == a[2]) && (a[2] == a[5]) && (a[5] == a[7]) && (a[1] == a[3]) && (a[3] == a[4]) && (a[4] == a[6]) 修改后,再次提交,仍然WA,检查之后发现没有判断是否是合法日期 再次修改,依然WA,又一次检查,发现i的范围给小了,我一开始只把n限制在了89991213,当时看到最大的数据范围就是这个,所以想当然的把89991213当成最大的,但是如果输入的n是89991213,那么它之后的回文日期必然大于89991213,终于AC了,但是代码写的还是挺烂的。。 总结来说,是个简单题,但是要注意细节 又用到了常考的判断日期的合法性
#include<bits/stdc++.h>
using namespace std;
int a[9];
int b[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int check1(int n) {
int k = 0;
int m = n;
while (n > 0) {
a[k++] = n % 10;
n /= 10;
}
if (a[0] == a[7] && a[1] == a[6] && a[2] == a[5] && a[3] == a[4]) {
return 1;
} else
return 0;
}
int check2(int n) {
int k = 0;
int m = n;
while (n > 0) {
a[k++] = n % 10;
n /= 10;
}
if ((a[0] != a[1]) && (a[0] == a[2]) && (a[2] == a[5]) && (a[5] == a[7]) && (a[1] == a[3]) && (a[3] == a[4]) && (a[4] == a[6])) {
return 1;
} else
return 0;
}
int judge(int year, int month, int day) {
if (month == 0 || month > 12) {
return 0;
}
if (month != 2) {
if (day > b[month] || day == 0)
return 0;
}
if (month == 2) {
if (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)) {
b[month] = 29;
if (day > b[month] || day == 0)
return 0;
} else {
b[month] = 28;
if (day > b[month] || day == 0)
return 0;
}
}
return 1;
}
int main() {
int n;
cin >> n;
int flag = 0;
int flag1 = 0;
for (int i = n + 1; i <= 99999999; i++) {
int year = i / 10000;
int month = i / 100 % 100;
int day = i % 100;
int ans = judge(year, month, day);
if (ans == 1) {
int flag1 = check1(i);
if (flag1 == 1) {
cout << i << endl;
break;
}
}
}
for (int i = n + 1; i <= 99999999; i++) {
int year = i / 10000;
int month = i / 100 % 100;
int day = i % 100;
int ans = judge(year, month, day);
if (ans == 1) {
int flag = check2(i);
if (flag == 1) {
cout << i << endl;
break;
}
}
}
}
蓝桥杯2020第十一届省赛第一场 第二题 纪念日 思路:算出这两个日期之间有多少天即可,注意闰年有29天
#include<bits/stdc++.h>
using namespace std;
int a[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
bool check(int year)
{
if(year%400==0||(year%4==0&&year%100!=0))
{
return true;
}
else
{
return false;
}
}
int main()
{
int sum=0;
for(int i=1921;i<=2020;i++)
{
bool flag=check(i);
if(flag)
{
a[2]=29;
}
else
{
a[2]=28;
}
if(i==1921)
{
for(int j=8;j<=12;j++)
{
sum+=a[j];
}
sum+=8;
}
else if(i==2020)
{
for(int j=1;j<=6;j++)
{
sum+=a[j];
}
sum+=1;
}
else
{
for(int j=1;j<=12;j++)
{
sum+=a[j];
}
}
}
cout<<sum*24*60<<endl;
}
蓝桥杯2020第十一届省赛第二场 第四题 跑步锻炼 思路一:暴力枚举从20000101到20201001的所有合法日期,如果日期合法,判断是不是月初或者周一,有个小问题,怎么去计算它是星期几,由2000年1月1日是周六,我们可以得出2000年1月2日是星期天,算出给定日期是从该天起过了x天,然后输出x%7,当天即为星期几,也就是找当前最近的是周日的那天开始枚举,最后别忘了加上1月1日的2千米和1月2日的1千米
#include<bits/stdc++.h>
using namespace std;
int a[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int check(int year, int month, int day) {
if (month == 0 || month > 12) {
return false;
}
if (month != 2) {
if (day > a[month] || day == 0)
return false;
}
if (month == 2) {
if (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)) {
a[month] = 29;
if (day > a[month] || day == 0)
return false;
} else {
a[month] = 28;
if (day > a[month] || day == 0)
return false;
}
}
return true;
}
int main() {
int ans=3;
int pass=0;
for (int i = 20000103; i <= 20201001; i++) {
int day = i % 100;
int month = i / 100 % 100;
int year = i / 10000;
bool flag = check(year, month, day);
if (flag) {
pass++;
int weekday=pass%7;
if(weekday==1||day==1)
{
ans+=2;
}
else
ans+=1;
}
}
cout<<ans<<endl;
}
思路二:后面看了看别人的做法,处理时间是比较巧妙的,感觉像是模拟,其中对星期几的处理也十分的巧妙
#include<bits/stdc++.h>
using namespace std;
int a[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int main() {
int year = 2000;
int month = 1;
int day = 1;
int ans = 0;
int weekday = 6;
while (year != 2020 || month != 10 || day != 1) {
if ((year % 400 == 0) || (year % 4 == 0) && (year % 100 != 0)) {
a[2] = 29;
} else {
a[2] = 28;
}
day++;
weekday = (weekday + 1) % 7;
if (day > a[month]) {
month++;
day = 1;
}
if (month > 12) {
month = 1;
year++;
}
if(day==1||weekday==1)
{
ans+=2;
}
else
{
ans+=1;
}
}
cout<<ans+2<<endl;
}*
总结 总结一下近几年有关日期类的问题,需要掌握以下几个点
- 判断闰年
- 检测日期的合法性
- 判断回文
- 给一个日期,告诉你是星期几,然后根据这个去计算另一个日期是星期几,一般找星期天的日期,以那天为基准点,该天起过了x天,然后输出x%7
int pass=0;
for (int i = 20000103; i <= 20201001; i++) {
int day = i % 100;
int month = i / 100 % 100;
int year = i / 10000;
bool flag = check(year, month, day);
if (flag) {
pass++;
int weekday=pass%7;
if(weekday==1||day==1)
{
ans+=2;
}
else
ans+=1;
}
}
void pass(int y, int m, int d, int n) {
while (n--) {
d++;
if (d > get(y, m)) m++, d = 1;
if (m > 12) y++, m = 1;
}
printf("%d-%02d-%02d\n", y, m, d);
}
int year = 2021;
int d = year, x = year;
for(int i = 0; i < 4; i++) {
d = d * 10 + x % 10;
x /= 10;
}
|