PAT乙級 1028. 人口普查 C語言
1028. 人口普查(20)
題目:
某城鎮進行人口普查,得到了全體居民的生日。現請你寫個程式,找出鎮上最年長和最年輕的人。
這裡確保每個輸入的日期都是合法的,但不一定是合理的——假設已知鎮上沒有超過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
注意:如果沒有有效生日日期,應輸出‘0’ (感覺這裡挺坑的。。。)
友情提示:如果你和我一樣,對於出生日期和年齡之間的關係傻傻分不清的話,那麼。。。請像我一樣在寫程式之前狂敲一下思路,免得寫著寫著就犯傻了。。。
思路:
* 判斷出生日期是否合法
* ……..if(合法)
* ……..對比出生日期:
* …………….找最大:出生日期越小–>出生早–>年齡大
* …………….找最小:出生日期越大–>出生晚–>年齡小
*
* Tip
* …….. [ 直接將使用者的出生”年/月/日“直接看作一個字串 ]
* 判斷是否合法: if( 200年前日期 < 使用者生日字串 < 今天日期) 生日合法
* 對比生日大小:
* …….. if(使用者A生日 ”早於“ 最大年齡者生日) 使用者A為最大年齡者
* …….. if(使用者B生日 ”晚於“ 最小年齡者生日) 使用者B為最小年齡者
程式碼如下:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define OLD "1814/09/06"//年齡最大的生日上界
#define YOUNG "2014/09/06"//年齡最小的生日下界
#define SIZE_NAME 6//名字長度+1
#define SIZE_BIR 11//生日字串長度+1
typedef struct{
char name[SIZE_NAME];
char birth[SIZE_BIR];
}AGE;
int main(void)
{
int N,countValid;
AGE data,max,min;//max表示最大年齡者,min表示最小年齡者
scanf("%d",&N);
countValid = 0;
char maxBirth[SIZE_BIR],minBirth[SIZE_BIR];//最大年齡者”生日“和最小年齡者”生日“
strcpy(maxBirth,YOUNG);
strcpy(minBirth,OLD);
for(int i = 0; i < N; i++ )
{
int isValid = 0;
scanf("%s %s",data.name,data.birth);
//判斷是否合法
if( strcmp(data.birth,OLD) >= 0 && strcmp(data.birth,YOUNG) <= 0 )
isValid = 1;
//如果生日合法
if(isValid)
{
countValid++;//計算有效資料數量
//找年齡最大者(生日日期< max的生日 -->出生更早,年齡更大)
if(strcmp(data.birth,maxBirth) < 0)
{
strcpy(maxBirth,data.birth);
max = data;
}
//找年齡最小者(生日日期 > min的生日 -->出生更晚,年齡更小)
if(strcmp(data.birth,minBirth) > 0)
{
strcpy(minBirth,data.birth);
min = data;
}
}
}
//輸出
if( !countValid )//如果沒有有效生日日期,輸出'0'
printf("0\n");
else
printf("%d %s %s\n",countValid,max.name,min.name);
return 0;
}
小結:
如何看待“輸入”對一個程式至關重要。 程式開始的時候,最首先的考慮應該是:要以什麼形式儲存資料。不同的資料儲存方式通常造就截然不同的演算法,因此花點時間考慮“資料結構”絕對是值得的。 乙級中並沒有涉及什麼高階資料結構,所以通常就是在字串/單字元/數值(包括整型/浮點型)/陣列/結構/指標之間權衡即可。