日期问题合集

日期问题合集

求解两个日期之间的差值

有两个日期,求两个日期之间的天数,如果两个日期是连续的我们规定他们之间的天数为两天。

输入格式

输入包含多组测试数据。

每组数据占两行,分别表示两个日期,形式为 YYYYMMDD

输出格式

每组数据输出一行,即日期差值。

数据范围

年份范围 [1,9999],
保证输入日期合法。

输入样例:

20110412 20110422

输出样例:

11

#include <bits/stdc++.h> using namespace std; const int N = 13; int months[]={0,31,28,31,30,31,30,31,31,30,31,30,31}; int a,b; int get(int x) { int y = x/10000; int m = x%10000/100; int d = x%100; if (y%4==0&&y%100!=0 || y%400==0) months[2]=29; else months[2]=28; while (m--) d+=months[m]; // 本年内的1~m月的天数 while (y--) d+=(y%4==0&&y%100!=0||y%400==0?366:365); // 加上1~y的所有年份的天数 return d; } int main() { while (cin>>a>>b) cout<<abs(get(a)-get(b))+1<<endl; return 0; }

回文日期问题

在日常生活中,通过年、月、日这三个要素可以表示出一个唯一确定的日期。

牛牛习惯用 8 位数字表示一个日期,其中,前 4 位代表年份,接下来 2 位代表月份,最后 2 位代表日期。

显然:一个日期只有一种表示方法,而两个不同的日期的表示方法不会相同。

牛牛认为,一个日期是回文的,当且仅当表示这个日期的 8 位数字是回文的。

现在,牛牛想知道:在他指定的两个日期之间(包含这两个日期本身),有多少个真实存在的日期是回文的。

一个 8 位数字是回文的,当且仅当对于所有的 $ i ( 1≤i≤8 ) i 9−i i $ 个数字)是相同的。

例如:

  • 对于 20161119 日,用 8 位数字 20161119 表示,它不是回文的。
  • 对于 201012 日,用 8 位数字 20100102 表示,它是回文的。
  • 对于 2010102 日,用 8 位数字 20101002 表示,它不是回文的。

输入格式

输入包括两行,每行包括一个 8 位数字。

第一行表示牛牛指定的起始日期 date1,第二行表示牛牛指定的终止日期 date2。保证 date1date2 都是真实存在的日期,且年份部分一定为 4 位数字,且首位数字不为 0

保证 date1 一定不晚于 date2

输出格式

输出共一行,包含一个整数,表示在 date1date2 之间,有多少个日期是回文的。

输入样例:

20110101 20111231

输出样例:

1

日期一共8位,那么我们可以枚举前4位来生成回文日期,然后判断:

  1. 回文日期是否合法
  2. 回文日期是否在给定的两个日期范围之内
#include <bits/stdc++.h> using namespace std; const int N = 13; int m[]={0,31,28,31,30,31,30,31,31,30,31,30,31}; int a,b; bool check(int date) { int year = date / 10000; int month = date % 10000 / 100; int day = date % 100; if (!month || month >= 13 || !day) return false; if (month != 2 && day > m[month]) return false; if (month == 2) { bool leap = year % 4 == 0 && year % 100 || year % 400 == 0; if (day > 28 + leap) return false; } return true; } int main() { cin>>a>>b; int ans = 0; for (int i=1;i<100000;i++) { int x=i,y=i; for (int j=0;j<4;j++) x = x*10+y%10,y/=10; if (check(x)&&x>=a&&x<=b) ans++; } cout<<ans<<endl; return 0; }

已知年份和天数,求是这年的几月几日

给定一个年份 y 和一个整数 d,问这一年的第 d 天是几月几日?

注意闰年的 2 月有 29 天。

满足下面条件之一的是闰年:

  1. 年份是 4 的整数倍,而且不是 100 的整数倍;
  2. 年份是 400 的整数倍。

输入格式

输入的第一行包含一个整数 y,表示年份,年份在 19002015 之间(包含 19002015)。

输入的第二行包含一个整数 $ d d 1 365 $ 之间。

输出格式

输出两行,每行一个整数,分别表示答案的月份和日期。

数据范围

$ 1900 \le y \le 2015 , 1 \le d \le 365 $

输入样例1:

2015 80

输出样例1:

3 21

输入样例2:

2000 40

输出样例2:

2 9

思路

就是从一月开始枚举,如果剩余天数能减去整月就减,减不了就确定了月份和天数的答案了。还是要注意一下二月和闰年的特判。

#include <bits/stdc++.h> using namespace std; const int N = 13; int m[]={0,31,28,31,30,31,30,31,31,30,31,30,31}; int a,b; int main() { cin>>a>>b; if (a%4==0&&a%100!=0||a%400==0) m[2]=29; else m[2]=28; int month=0,day=0; for (int i=1;i<13;i++) { if (b>m[i]) // 够整月减 { b-=m[i]; month++; } else // 不够整月减 { month++; day = b; break; } } cout<<month<<endl<<day<<endl; return 0; }

给出一个日期,输出下一天的日期

编写一个日期类,要求按 xxxx-xx-xx 的格式输出日期,实现加一天的操作。

输入格式

第一行包含整数 T,表示共有 T 组测试数据。

每组数据占一行,包含 3 个用空格隔开的整数,分别表示年月日。

输出格式

每组数据输出一行,一个结果,按 xxxx-xx-xx 的格式输出,表示输入日期的后一天的日期。

数据范围

输入日期保证合法且不会出现闰年。
年份范围 [1000,3000]

输入样例:

2 1999 10 20 2001 1 31

输出样例:

1999-10-21 2001-02-01

只需要特判一下:

  1. 本年的最后一天
  2. 本月的最后一天
  3. 正常日期
#include <bits/stdc++.h> using namespace std; const int N = 13; int m[]={0,31,28,31,30,31,30,31,31,30,31,30,31}; int n; int main() { cin>>n; while (n--) { int a,b,c; cin>>a>>b>>c; // 特判本年的最后一天 if (b!=12&&c==m[b]) printf("%d-%02d-%02d\n",a,b+1,1); // 特判本月的最后一天 else if (b==12&&c==m[b]) printf("%d-%02d-%02d\n",a+1,1,1); // 正常的日期 else printf("%d-%02d-%02d\n",a,b,c+1); } return 0; }

给出年份 y 和一年中的第 d 天,算出第 d 天是几月几号。

给出年份 y 和一年中的第 d 天,算出第 d 天是几月几号。

输入格式

输入包含多组测试数据。

每组数据占一行,包含两个整数 yd

输出格式

每组数据输出一行一个结果,格式为 yyyy-mm-dd

数据范围

输入最多包含 100 组数据,
$ 1 \le y \le 3000 , 1 \le d \le 366 $,
数据保证合法。

输入样例:

2000 3 2000 31 2000 40 2000 60 2000 61 2001 60

输出样例:

2000-01-03 2000-01-31 2000-02-09 2000-02-29 2000-03-01 2001-03-01

和给出年份与天数,确定几月几日是一模一样的题目。就是直接模拟即可。如果剩余天数大于当前月的天数,更新月份和剩余天数;如果剩余天数不足当前月的天数,更新月份,确定月份和当前月的几号,相当于确定了答案,退出。

#include <bits/stdc++.h> using namespace std; const int N = 13; int m[]={0,31,28,31,30,31,30,31,31,30,31,30,31}; int a,b; int main() { while (cin>>a>>b) { if (a%4==0&&a%100!=0||a%400==0) m[2]=29; else m[2]=28; int year=a,month=0,d=0; for (int i=1;i<13;i++) { if (b>m[i]) { month++; b-=m[i]; } else { month++; d=b; break; } } printf("%04d-%02d-%02d\n",year,month,d); } return 0; }

从当前日期开始,到指定日期,确定是星期几

今天是 2012412 日星期四,编写程序,输入今天开始到 1231 日之间的任意日期,输出那一天是星期几。

输入格式

共两行,第一行包含一个整数 m,表示询问日期的月份。

第二行包含一个整数 d,表示询问日期的为该月的第几天。

输出格式

输出询问日期是星期几。

注意,要用英文表示。

周一到周日的英文表示如下:

"Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"

数据范围

$ 4 \le m \le 12 , 1 \le d \le 31 $,
保证日期合法。

输入样例:

5 20

输出样例:

Sunday

其实这道题的本质就是求解这两个日期之间的天数是多少。确定好之后,天数Mod7,即可确定是星期几。但这里有个细节需要处理一下:当前开始的日期是星期四,因此week数组中的顺序应该是4567123

#include<bits/stdc++.h> using namespace std; int a[13]={0,31,28,31,30,31,30,31,31,30,31,30,31}; // 因为这天是星期四开始的,因此星期的第一个位置应该是星期四 string week[7]={"Thursday","Friday","Saturday","Sunday","Monday","Tuesday","Wednesday",}; int main() { int n,m,day1=0,day2=0; cin>>n>>m; for(int i=1;i<4;i++)day1+=a[i]; day1+=12; for(int i=1;i<n;i++)day2+=a[i]; day2+=m; // 两个日期之间的天数即可确定 cout<<week[(day2-day1)%7]<<endl; return 0; }

3391. 今年的第几天? - AcWing题库

输入年、月、日,计算该天是本年的第几天。

注意闰年的 2 月有 29 天。

满足下面条件之一的是闰年:

  • 年份是 4 的整数倍,而且不是 100 的整数倍;
  • 年份是 400 的整数倍。

输入格式

输入包含多组测试数据。

每组数据占一行,包含三个整数 Y,M,D,表示年、月、日。

输出格式

每组数据输出一个整数,占一行,表示输入给定的年、月、日对应本年的第几天。

数据范围

$ 1 \le Y \le 3000 , 1 \le M \le 12 , 1 \le D \le 31 , 100 $ 组测试数据。
保证所有日期都是合法的。

输入样例:

1990 9 20 2000 5 1

输出样例:

263 122

没啥好说的,从1~m-1月先枚举求得整月份的天数,再单独加上最后的零散天数即可.

属于是典型的已知年月日,求解时本年度的第几天。

当然,如果本题扩展到不仅限于本年份了,即可能从1999年1月1日开始到当前年月日经过了多少天类似这种要求,那么就变成了求解两个具体日期相隔多少天的问题了。那么就是像之前类似的题目求解方法一样,从1年1月1日开始计算(即从头)到第一个日期求解天数day1,同理求解从头到第二个日期的天数day2,相减作差即可得到答案。

#include <bits/stdc++.h> using namespace std; const int N = 13; int months[]={0,31,28,31,30,31,30,31,31,30,31,30,31}; int main() { int y,m,d; while (cin>>y>>m>>d) { if (y%4==0&&y%100!=0||y%400==0) months[2]=29; else months[2]=28; int ans = 0; for (int i=1;i<m;i++) ans+=months[i]; ans+=d; cout<<ans<<endl; } return 0; }

3489. 星期几 - AcWing题库

已知 111 日是星期一。

现在给定一个日期,请你判断是星期几。

注意闰年的 2 月有 29 天。

满足下面条件之一的是闰年:

  1. 年份是 4 的整数倍,而且不是 100 的整数倍;
  2. 年份是 400 的整数倍。

输入格式

输入包含多组测试数据。

每组数据占一行,包含一个整数 d 表示日,一个字符串 m 表示月,一个整数 y 表示年。

月份 112,依次如下所示:

January, February, March, April, May, June, July, August, September, October, November, December

输出格式

每组数据输出一行结果,输出一个字符串表示给定日期是星期几。

周一至周日依次如下所示:

Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday

数据范围

1000y3000,
给定日期保证合法。
每个输入最多包含 100 组数据。

输入样例:

9 October 2001 14 October 2001

输出样例:

Tuesday Sunday

这个题本质还是已知具体的日期,求从元年1月1日(包含)到现在经过的天数,然后根据初始的时间节点是星期几,确定当前日期是星期几的问题。注意月份数字与字符串哈希表的写法、月份和月份天数的数组打表写法、星期的打表写法等细节。

#include <bits/stdc++.h> using namespace std; const int N = 13; int month[]={0,31,28,31,30,31,30,31,31,30,31,30,31}; string week[]={"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"}; unordered_map<string,int>S={ {"January",1}, {"February",2}, {"March",3}, {"April",4}, {"May",5}, {"June",6}, {"July",7}, {"August",8}, {"September",9}, {"October",10}, {"November",11}, {"December",12} }; int main() { int d,y; string s; while (cin>>d>>s>>y) { int m = S[s]; if (y%4==0&&y%100!=0||y%400==0) month[2]=29; else month[2]=28; int ans = 0; for (int i=1;i<y;i++) ans+=(i%4==0&&i%100!=0||i%400==0 ? 366:365); for (int i=1;i<m;i++) ans+=month[i]; ans+=d; // 注意:星期的对应是0~6对应星期一到天,去掉第一天的情况 cout<<week[(ans%7-1+7)%7]<<endl; } return 0; }

1341. 十三号星期五 - AcWing题库

十三号星期五真的很不常见吗?

每个月的十三号是星期五的频率是否比一周中的其他几天低?

请编写一个程序,计算 N 年内每个月的 13 号是星期日,星期一,星期二,星期三,星期四,星期五和星期六的频率。

测试的时间段将会开始于 190011 日,结束于 1900+N11231日。

一些有助于你解题的额外信息:

  1. 190011 日是星期一。
  2. 在一年中,4 月、6 月、9 月、11 月每个月 30 天,2 月平年 28 天,闰年 29 天,其他月份每个月31天。
  3. 公历年份是 4 的倍数且不是 100 的倍数的年份为闰年,例如 1992 年是闰年,1990 年不是闰年。
  4. 公历年份是整百数并且是 400 的倍数的也是闰年,例如1700年,1800年,1900年,2100年不是闰年,2000年是闰年。

输入格式

共一行,包含一个整数 N

输出格式

共一行,包含七个整数,整数之间用一个空格隔开,依次表示星期六,星期日,星期一,星期二,星期三,星期四,星期五在十三号出现的次数。

数据范围

1N400

输入样例:

20

输出样例:

36 33 34 33 35 35 34

抽象日期模型还是:已知初始状态的日期年月日,求一个新的日期是星期几。

那么我们的思路还是求解这个新的日期与起点的天数,去取模7计算星期几。

#include <bits/stdc++.h> using namespace std; const int N = 13; int cnt[10]; int month[]={0,31,28,31,30,31,30,31,31,30,31,30,31}; int n,w,x; int main() { cin>>n; int days = 0; for (int y=1900;y<=1900+n-1;y++) { if (y%4==0&&y%100!=0||y%400==0) month[2]=29; else month[2]=28; for (int i=1;i<=12;i++) { cnt[(days+13-1+7)%7]++; days+=month[i]; } } for (int i=5,j=0;j<7;i=(i+1)%7,j++) cout<<cnt[i]<<" "; puts(""); return 0; }

3573. 日期累加 - AcWing题库

设计一个程序能计算一个日期加上若干天后是什么日期。

输入格式

第一行包含整数 T,表示共有 T 组测试数据。

每组数据占一行,包含四个整数 y,m,d,a,分别表示给定日期的年、月、日和累加的天数。

输出格式

每组数据输出一行,一个结果,每行按 yyyy-mm-dd 的格式输出。

数据范围

1T1000
$ 1000 \le y \le 3000 , 1 \le m \le 12 , 1 \le d \le 31 , 1 \le a \le 10^6 $,
保证输入日期合法。

输入样例:

1 2008 2 3 100

输出样例:

2008-05-13

抽象这道题,就是已知当前日期,求若干天后的日期。一种比较容易想到的写法就是不断让天数--,直到走到那一天。但会TLE

#include <bits/stdc++.h> using namespace std; const int N = 13; int month[]={0,31,28,31,30,31,30,31,31,30,31,30,31}; bool check(int y) { if (y%4==0&&y%100!=0||y%400==0) return true; return false; } int T,y,m,d,a; int main() { scanf("%d",&T); while (T--) { scanf("%d%d%d%d",&y,&m,&d,&a); while (a--) { d++; if (check(y)) month[2]=29; else month[2]=28; if (d>month[m]) { m++; d=1; } if (m>12) { y++; m=1; } } printf("%02d-%02d-%02d\n",y,m,d); } return 0; }

另一种写法就是先把总天数算出,然后从m这个月开始枚举,边枚举边更新剩余天数等信息。

//按月进行累加进位,最后剩下的就是号 #include <bits/stdc++.h> using namespace std; int ms[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; bool isleap(int y) { return y%4 == 0 && y%100 != 0 || y%400 == 0; } int get(int y, int m) { if (m != 2) return ms[m]; return 28 + isleap(y); } int main() { int n, y, m, d, a, day; scanf("%d", &n); while (n--) { scanf("%d%d%d%d", &y, &m, &d, &a); a += d; //日累加到加的总天数上 while (a > get(y, m)) { //加的天数大于该月天数,该月就可以完整过到下一个月 a -= get(y, m); m++; if (m > 12) m = 1, y++; } printf("%04d-%02d-%02d\n", y, m, a); } return 0; }

AcWing 3498. 日期差值 - AcWing

有两个日期,求两个日期之间的天数,如果两个日期是连续的我们规定他们之间的天数为两天。

输入格式

输入包含多组测试数据。

每组数据占两行,分别表示两个日期,形式为 YYYYMMDD

输出格式

每组数据输出一行,即日期差值。

数据范围

年份范围 [1,9999],
保证输入日期合法。

输入样例:

20110412 20110422

输出样例:

11

典型的求两个具体日期之间的差值的问题。思路就是分别求出两个日期距离1年1月1日经过的天数,然后相减+1即可。

#include<bits/stdc++.h> using namespace std; //存储每月的天数求出来 int a[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};//从a[1]开始存 //差分思想 int days(int x)//days函数用于计算到0000/00/00的天数 { int n = x / 10000;//年 int y = x % 10000 / 100;//月 int r = x % 10000 % 100;//日 //首先更新一下计算年份的二月天数有多少 //闰年包括普通闰年和世纪闰年 //普通闰年年分是4倍数不是100倍数(),世纪闰年是400的倍数, //即100的倍数不是4的倍数不是闰年,如1900 //判断闰年 if(n % 4 == 0 && n % 100 != 0||n % 400 == 0) a[2]=29; else //不加这个会错 a[2]=28; // a[2] = ( n % 4 == 0 && n % 100 != 0 || n % 400 == 0 ? 29 : 28);//等价写法 //统计当前年份的总天数 while(y --) r += a[y];//把每个月的天数相加,注意初值为把未满一月的天数 //计算从公元1年开始开始,一直到去年最后一天,不是到0000年 while(n --) r += (n % 4 == 0 && n % 100 != 0||n % 400 == 0 ? 366 : 365);//闰年366天,平年365天 return r;//返回一共的天数 } int main() { int a,b; while(cin >> a >> b) cout<< abs( days(a) - days(b) )+1 << endl; //注意需要加一,相邻的两天日期相差1,天数相差2 }


__EOF__

本文作者dfl
本文链接https://www.cnblogs.com/sdnu-dfl/p/17294360.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   勇敢龙龙  阅读(95)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
点击右上角即可分享
微信分享提示