化繁就简(结构体在算法中的运用)

不念不忘少年蓝@ 2024-03-31 09:35 90阅读 0赞

化繁就简(结构体在算法中的运用)

题目

某城镇进行人口普查,得到了全体居民的生日。现请你写个程序,找出镇上最年长和最年轻的人。

这里确保每个输入的日期都是合法的,但不一定是合理的——假设已知镇上没有超过200岁的老人,而今天是2014年9月6日,所以超过200
岁的生日和未出生的生日都是不合理的,应该被过滤掉。

输入描述:

输入在第一行给出正整数N,取值在(0, 105];随后N行,每行给出1个人的姓名(由不超过5个英文字母组成的字符串)、以及
按“yyyy/mm/dd”(即年/月/日)格式给出的生日。题目保证最年长和最年轻的人没有并列。

输出描述:

在一行中顺序输出有效生日的个数、最年长人和最年轻人的姓名,其间以空格分隔。

输入例子:

5
John 2001/05/12
Tom 1814/09/06
Ann 2121/01/30
James 1814/09/05
Steve 1967/11/20

输出例子:

3 Tom John
*/

我的算法

  1. #include <stdio.h>
  2. #include <string.h>
  3. int main(void)
  4. {
  5. int n, cnt = 0;
  6. int y, m, d;
  7. int t, flag = 1, flag2 = 0;
  8. int i, j, k;
  9. int mi, mj, mk, ni, nj, nk;
  10. char name1[10], name2[10];
  11. char name[10];
  12. scanf ("%d", &n);
  13. t = n;
  14. getchar ();
  15. while (t--)
  16. {
  17. scanf (" %s %d/%d/%d", name, &y, &m, &d);
  18. if ((1814 <= y && y <= 2014))
  19. {
  20. if (y == 2014)
  21. {
  22. if (m <= 9 && d <= 6)
  23. {
  24. cnt++;
  25. flag2 = 1;
  26. }
  27. }
  28. else if (y == 1814)
  29. {
  30. if (y >= 9 && d >= 6)
  31. {
  32. cnt++;
  33. flag2 = 1;
  34. }
  35. }
  36. else
  37. {
  38. cnt++;
  39. flag2 = 1;
  40. }
  41. if (flag && flag2)
  42. {
  43. strcpy (name1, name);
  44. mi = 2014 - y;
  45. mj = m - 9;
  46. mk = d - 6;
  47. strcpy (name2, name);
  48. ni = 2014 - y;
  49. nj = m - 9;
  50. nk = d - 6;
  51. flag = 0;
  52. }
  53. if (flag == 0)
  54. {
  55. i = 2014 - y;
  56. j = m - 9;
  57. k = d - 6;
  58. if (i >= mi)
  59. {
  60. if (i == mi)
  61. {
  62. if (j >= mj)
  63. {
  64. if (j == mj)
  65. {
  66. if (k > mk)
  67. {
  68. strcpy (name1, name);
  69. mi = i;
  70. mj = j;
  71. mk = k;
  72. }
  73. }
  74. else
  75. {
  76. strcpy (name1, name);
  77. mi = i;
  78. mj = j;
  79. mk = k;
  80. }
  81. }
  82. }
  83. else
  84. {
  85. strcpy (name1, name);
  86. mi = i;
  87. mj = j;
  88. mk = k;
  89. }
  90. }
  91. if (i <= ni)
  92. {
  93. if (i == ni)
  94. {
  95. if (j <= nj)
  96. {
  97. if (j == nj)
  98. {
  99. if (k < nk)
  100. {
  101. strcpy (name2, name);
  102. ni = i;
  103. nj = j;
  104. nk = k;
  105. }
  106. }
  107. else
  108. {
  109. strcpy (name2, name);
  110. ni = i;
  111. nj = j;
  112. nk = k;
  113. }
  114. }
  115. }
  116. else
  117. {
  118. strcpy (name2, name);
  119. ni = i;
  120. nj = j;
  121. nk = k;
  122. }
  123. }
  124. }
  125. }
  126. }
  127. printf ("%d ", cnt);
  128. for (i = 0; name1[i] != '\0'; i++)
  129. {
  130. putchar (name1[i]);
  131. }
  132. putchar (' ');
  133. for (i = 0; name2[i] != '\0'; i++)
  134. {
  135. putchar (name2[i]);
  136. }
  137. return 0;
  138. }
  139. */

好的算法1(结构体)

c语言
// 这是用的结构体原理,这也是一般人看见这个题目一般的好的想法
// 个人推荐,但是后面还有个更好的写法

  1. #include<stdio.h>
  2. struct birth
  3. {
  4. char name[6];
  5. int y;
  6. int m;
  7. int d;
  8. }a, max, min;
  9. int main()
  10. {
  11. int n, cnt = 0;
  12. scanf("%d", &n); // 几个待处理的数据
  13. max.y = 2014; max.m = 9;max.d = 7; // 两个边界
  14. min.y = 1814; max.m = 9; max.d = 5;
  15. cnt = n;
  16. for(int i = 0; i < n; i++)
  17. {
  18. scanf("%s %d/%d/%d", &a.name, &a.y, &a.m, &a.d); // 按题目要求的输入
  19. if(a.y > 2014 || (a.y == 2014 && a.m > 9) || (a.y == 2014 && a.m == 9 && a.d > 6) || a.y < 1814 || (a.y == 1814 && a.m < 9) || (a.y == 1814 && a.m == 9 && a.d < 6))
  20. {
  21. cnt--; // 这个if条件里面包含的了所有非法的条件,每次不满足条件就cnt(总处理个数-1)
  22. continue; // 让后跳过这次循环
  23. }
  24. if(a.y < max.y || (a.y == max.y && a.m < max.m) || (a.y == max.y && a.m == max.m && a.d < max.d))
  25. {
  26. max = a; // 这个是找最大的情况的一个判断
  27. }
  28. if(a.y > min.y || (a.y == min.y && a.m > min.m) || (a.y == min.y && a.m == min.m && a.d > min.d))
  29. {
  30. min = a; // 这个是找最小的情况的一个判断
  31. }
  32. }
  33. printf("%d", cnt); // 输出
  34. if(cnt != 0)
  35. {
  36. printf(" %s %s",max.name, min.name);
  37. }
  38. return 0;
  39. }

好的算法2(不使用结构体)

  1. // 这是一个不用结构体的方法
  2. #include <iostream>
  3. using namespace std;
  4. #include <cstring>
  5. int main()
  6. {
  7. char max[6], min[6], name[6]; // 用来装名字的
  8. int year, mon, day; // 用来装年月日的
  9. int n, cnt = 0, flag = 0;
  10. long long bm = 20140906, bi = 18140906, temp, m1 = 0, m2 = 0; // 看到这里就知道这个原理了,就是把出生日期转化为数字来对比,一定要用long long 不然可能数据溢出
  11. scanf ("%d", &n); // 待处理的数据个数
  12. for (int i = 0; i < n; i++)
  13. {
  14. scanf ("%s %d/%d/%d", name, &year, &mon, &day); // 输入年月日
  15. temp = year * 10000 + mon * 100 + day; // 进行格式转换
  16. if (temp >= bi && temp <= bm) // 简单的判断看看是否在要求的界限范围内
  17. {
  18. cnt++;
  19. if (flag == 0) // 标记用的,最大,最小都用第一个初始化
  20. {
  21. m1= temp;
  22. strcpy(max, name);
  23. m2 = temp;
  24. strcpy(min, name);
  25. flag = 1;
  26. }
  27. else
  28. {
  29. if (temp > m1) // 这里就是很常见的找最大,最小的判断了
  30. {
  31. m1 = temp;
  32. strcpy(max, name);
  33. }
  34. if (temp < m2)
  35. {
  36. m2 = temp;
  37. strcpy(min, name);
  38. }
  39. }
  40. }
  41. }
  42. cout << cnt << " " << min << " " << max << endl;
  43. return 0;
  44. }

发表评论

表情:
评论列表 (有 0 条评论,90人围观)

还没有评论,来说两句吧...

相关阅读

    相关 转换实现方式。

    当网站遇到国际化问题时,会考虑将网站的文字转换语言形式。通常涉及这种国际化问题时会有多种实现方式。首先要将网站的编码格式设置成支持多种语言的UTF-8编码,然后对页面进行本地化

    相关 系列原创教程

    这是一个小巧的客户端套接字类,类名、函数名和变量名均采用匈牙利命名法。小写的x代表我的姓氏首字母(谢欣能),个人习惯而已,如有雷同,纯属巧合。 CxClientSocket的