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

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

题目

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

这里确保每个输入的日期都是合法的,但不一定是合理的——假设已知镇上没有超过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
*/

我的算法

#include <stdio.h>
#include <string.h>

int main(void)
{
	int n, cnt = 0;
	int y, m, d;
	int t, flag = 1, flag2 = 0;
	int i, j, k;
	int mi, mj, mk, ni, nj, nk;
	char name1[10], name2[10];
	char name[10];
	scanf ("%d", &n);
	t = n;
	getchar ();
	while (t--)
	{
		scanf (" %s %d/%d/%d", name, &y, &m, &d);
		if ((1814 <= y && y <= 2014))
		{
			if (y == 2014)
			{
				if (m <= 9 && d <= 6)
				{
				
					cnt++;
					flag2 = 1;
				}
			}
			else if (y == 1814)
			{
				if (y >= 9 && d >= 6)
				{
					cnt++;
					flag2 = 1;
				}
			}
			else
			{
				cnt++;
				flag2 = 1;
			}
			if (flag && flag2)
			{
				strcpy (name1, name);
				mi = 2014 - y;
				mj = m - 9;
				mk = d - 6;
				strcpy (name2, name);
				ni = 2014 - y;
				nj = m - 9;
				nk = d - 6;
				flag = 0;
			}
			if (flag == 0)
			{
				i = 2014 - y;
			j = m - 9;
			k = d - 6;
			if (i >= mi)
			{
				if (i == mi)
				{
					if (j >= mj)
					{
						if (j == mj)
						{
							if (k > mk)
							{
								
								strcpy (name1, name);
								mi = i;
								mj = j;
								mk = k;
							}
						}
						else
						{
							strcpy (name1, name);
							mi = i;
							mj = j;
							mk = k;
						}
					}
				}
				else
				{
					strcpy (name1, name);
					mi = i;
					mj = j;
					mk = k;
				}
			}
			if (i <= ni)
			{
				if (i == ni)
				{
					if (j <= nj)
					{
						if (j == nj)
						{
							if (k < nk)
							{
								
								strcpy (name2, name);
								ni = i;
								nj = j;
								nk = k;
							}
						}
						else
						{
							strcpy (name2, name);
							ni = i;
							nj = j;
							nk = k;
						}
					}
				}
				else
				{
					strcpy (name2, name);
					ni = i;
					nj = j;
					nk = k;
				}
			}
			}
			
			
		}
	}
	printf ("%d ", cnt);
	for (i = 0; name1[i] != '\0'; i++)
	{
		putchar (name1[i]);
	}
	putchar (' ');
	for (i = 0; name2[i] != '\0'; i++)
	{
		putchar (name2[i]);
	}
	return 0;
}
*/ 

好的算法1(结构体)

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

#include<stdio.h> 
struct birth		
	{
		char name[6];
		int y;
		int m;
		int d;
	}a, max, min;
int main()
{	
	int n, cnt = 0;
	scanf("%d", &n);   // 几个待处理的数据 
	max.y = 2014; max.m = 9;max.d = 7;     // 两个边界 
	min.y = 1814; max.m = 9; max.d = 5;	
	cnt = n; 
	for(int i = 0; i < n; i++)
	{
		scanf("%s %d/%d/%d", &a.name, &a.y, &a.m, &a.d);  // 按题目要求的输入 
	
		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))
		{
			cnt--;			// 这个if条件里面包含的了所有非法的条件,每次不满足条件就cnt(总处理个数-1) 
			continue;		// 让后跳过这次循环 
		}
		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))
		{
			max = a;		// 这个是找最大的情况的一个判断 
		}
		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))
		{
			min = a;		// 这个是找最小的情况的一个判断 
		}
	}
	printf("%d", cnt);		// 输出 
	if(cnt != 0)
	{
		printf(" %s %s",max.name, min.name);
	}
	
	return 0;
 }  

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

// 这是一个不用结构体的方法 
#include <iostream>
using namespace std;
#include <cstring>

int main()
{
	char max[6], min[6], name[6];  // 用来装名字的 
	int year, mon, day;		// 用来装年月日的 
	int n, cnt = 0, flag = 0;		 
	long long bm = 20140906, bi = 18140906, temp, m1 = 0, m2 = 0;  // 看到这里就知道这个原理了,就是把出生日期转化为数字来对比,一定要用long long 不然可能数据溢出 
	scanf ("%d", &n);  // 待处理的数据个数 
	for (int i = 0; i < n; i++)
	{
		scanf ("%s %d/%d/%d", name, &year, &mon, &day); // 输入年月日 
		temp = year * 10000 + mon * 100 + day;  // 进行格式转换 
		if (temp >= bi && temp <= bm)	// 简单的判断看看是否在要求的界限范围内 
		{
			cnt++;
			if (flag == 0)				// 标记用的,最大,最小都用第一个初始化 
			{
				m1= temp;
				strcpy(max, name);
				m2 = temp;
				strcpy(min, name);
				flag = 1;
			}
			else
			{
				if (temp > m1)   // 这里就是很常见的找最大,最小的判断了 
				{
					m1 = temp;
					strcpy(max, name);
				}
				if (temp < m2)
				{
					m2 = temp;
					strcpy(min, name);
				}
			}
		}
	}
	cout << cnt << " " << min << " " << max << endl;
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

极客李华

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值