• C/C++蓝桥杯之日期问题


    问题描述:小明正在整理一批文献,这些文献中出现了很多日期,小明知道这些日期都在1960年1月1日至2059年12月31日之间,令小明头疼的是,这些日期采用的格式非常不统一,有采用年/月/日的,有采用月/日/年的,还有采用日/月/年的,更加麻烦的是年份都省略了前两位,使得文献上的一个日期存在很多可能的日期与其对应。

    例如02/03/04,可能是2002年03月04日、2004年02月03日或2004年03月02日。

    程序输入格式:AA/BB/CC(0<=A,B,C<=9)

    输出格式:输出若干个不相同的日期,每个日期一行格式是:''yyyy-mm-dd''多个日期按从早到晚的顺序排列。

    分析:本题的思路很简单,将输入的三个数据分别进行年,月,日的合法判断,如果合法就输出,但是求解本题要注意以下两点。

    (1)月份数据的表示

    由于每月的天数没有规律性,所以最好的方法就是利用数组将每月的天数表示出来,如:

    int days[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};

    这里还要注意闰年问题,如果是闰年,则二月的数据就会不同,可以采用另一个数组存储

    如:int leapdays[13]={0,31,29,31,30,31,30,31,31,30,31,30,31};

    (2)合法年/月/日的存储

    对于一组数据可能会出现重复的合法年/月/日。例如:01/01/01,这三组合法数据都是2001/01/01,所以这要进行去重。

    去重时,可以采用直接判断三组数据是否相等的方法,也可以利用C++ STL中的set容器进行自动去重。

    用C语言: 

    1. #define _CRT_SECURE_NO_WARNINGS 1
    2. #include<stdio.h>
    3. int days[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };//不是闰年的时候
    4. int leapdays[13] = { 0,31,29,31,30,31,30,31,31,30,31,30,31 };//是闰年的时候
    5. int data[4][4];//用来存放日期
    6. int i;//用于数组的序号
    7. int leapyear(int year)//判断是否是闰年
    8. {
    9. if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0)
    10. {
    11. return 1;
    12. }
    13. else
    14. {
    15. return 0;
    16. }
    17. }
    18. void check(int y, int m, int d)
    19. {
    20. if (y >= 60)//年份的后两位大于60,说明应该是19年开头
    21. {
    22. y = 19 * 100 + y;
    23. }
    24. else//否则是20年开头
    25. {
    26. y = 20 * 100 + y;
    27. }
    28. if (m > 12)
    29. return;
    30. if(leapyear(y))//判断是否是闰年,采用对应的数组
    31. {
    32. if(leapdays[m]<d)
    33. return;
    34. }
    35. else
    36. {
    37. if(days[m]<d)
    38. return;
    39. }
    40. if (i > 0)//进行去重处理
    41. {
    42. for (int j = 0; j < i; j++)
    43. {
    44. if (data[j][0] == y && data[j][1] == m && data[j][2] == d)//判断日期是不是合法
    45. return;
    46. }
    47. }
    48. data[i][0] = y;
    49. data[i][1] = m;
    50. data[i][2] = d;
    51. i++;
    52. }
    53. int main()
    54. {
    55. int a, b, c, e, f, g;
    56. int d[3];
    57. i = 0;
    58. scanf("%d/%d/%d", &a, &b, &c);
    59. check(a, b, c);//分别互换日期查看是否成立
    60. check(c, a, b);
    61. check(c, b, a);
    62. for (int j = 0; j < i; j++)
    63. {
    64. d[j] = data[j][0] * 10000 + data[j][1] * 100 + data[j][2];
    65. }
    66. for (int m = 0; m < i; m++)//按从早到晚的顺序排列
    67. {
    68. for (int n=0; n < i - 1 - m; n++)
    69. {
    70. if (d[n] > d[n + 1])
    71. {
    72. int tmp = d[n];
    73. d[n] = d[n + 1];
    74. d[n + 1] = tmp;
    75. }
    76. }
    77. }
    78. for (int j = 0; j < i; j++)//打印
    79. {
    80. e = d[j] / 10000;
    81. f = (d[j] / 100) % 100;
    82. g = d[j] % 100;
    83. printf("%d-%02d-%02d\n", e, f, g);
    84. }
    85. return 0;
    86. }

    用C++:

    1. #include<bits/stdc++.h>
    2. using namespace std;
    3. struct date //定义一个结构体存放日期
    4. {
    5. int year;
    6. int month;
    7. int day;
    8. }que[4];
    9. int s=0; //用于结构体的序号
    10. int cmp(date x,date y);//比较函数sort的参数,定义了怎样排序
    11. int leapyear(int year);//用于判断是不是闰年
    12. int judge_date(int year,int month,int day);//判断日期是不是合法
    13. void judge(int year,int month,int day);//主要调用上面函数,把日期存进数组
    14. void judge(int year,int month,int day)
    15. {
    16. int flag=1; //标记日期是否重复
    17. if(year>=60)//年份的后两位大于60,说明应该是19年开头
    18. year = 19* 100 + year;
    19. else
    20. year = 20* 100 + year;
    21. if(judge_date(year,month,day))
    22. { //如果日期合法
    23. for(int i=0;i<s;i++)
    24. { //判断结构体中是否已经存在相同的日期
    25. if(que[i].day==day&&que[i].month==month&&que[i].year==year)
    26. {
    27. flag=0;
    28. break;
    29. }
    30. }
    31. if(flag)
    32. { //如果没有相同的日期就存进结构体中
    33. que[s].year=year;
    34. que[s].month=month;
    35. que[s].day=day;
    36. s++;
    37. }
    38. }
    39. }
    40. int judge_date(int year,int month,int day) //判断日期是否合法
    41. {
    42. int sum;
    43. switch(month) //判断输入的月份一共有多少天,和输入的天数比较
    44. {
    45. case 1: case 3: case 5: case 7: case 8: case 10: case 12:
    46. sum=31;
    47. break;
    48. case 4:case 6: case 9: case 11:
    49. sum=30;
    50. break;
    51. case 2:
    52. sum=28;
    53. break;
    54. }
    55. if(month==2&&leapyear(year))
    56. sum=29;
    57. if(sum>=day&&day>0&&month>=1&&month<=12) //如果天数小于该月总天数,且大于0,月份也在1~12,则合法
    58. return 1;
    59. else
    60. return 0;
    61. }
    62. int leapyear(int year)
    63. { //判断是否闰年
    64. if(year%4==0 && year%100!=0 || year%400==0)
    65. return 1;
    66. else
    67. return 0;
    68. }
    69. int cmp(date x,date y)
    70. { //比较函数
    71. if(x.year<y.year) //年份按递增排序
    72. return 1;
    73. else
    74. if(x.year==y.year)
    75. { //如年份相同,比较月份
    76. if(x.month<y.month)
    77. return 1;
    78. else
    79. if(x.month==y.month) //如月份相同,比较天数
    80. {
    81. if(x.day<y.day)
    82. return 1;
    83. }
    84. }
    85. return 0;
    86. }
    87. int main()
    88. {
    89. int a,b,c;
    90. scanf("%d/%d/%d",&a,&b,&c);
    91. judge(a,b,c);//分别把日期换位置,看是否合法
    92. judge(c,a,b);
    93. judge(c,b,a);
    94. sort(que,que+s,cmp);//按从早到晚的顺序排列
    95. for(int i=0;i<s;i++)//输法日期
    96. printf("%d-%02d-%02d\n",que[i].year,que[i].month,que[i].day);
    97. return 0;
    98. }

  • 相关阅读:
    vue模板语法(下集)
    软件考试学习笔记(希赛)
    企业清算有哪些类型?在哪里可以查看相关公告?
    面试:谈一下你对Nginx的理解
    html设置背景图大小,自动拉伸背景图
    软件项目管理期末复习---项目立项
    【进程与线程】进程与线程 Q&A
    [极致用户体验] 我又来帮掘金修专栏bug了,顺便教你个超牛逼的分割线CSS!
    Chatgpt批量改写文章网页版可多开软件-自动登录换号生成word或者TXT
    LLVM学习笔记(60)
  • 原文地址:https://blog.csdn.net/2301_80002696/article/details/136575257