1. 程式人生 > >PAT-B 1028. 人口普查(20)

PAT-B 1028. 人口普查(20)

題目連結在此

第一次感覺自己的想法比《演算法筆記》的“酷炫”,開心~
我的思路也是脫胎於《演算法筆記》對這個題目的解法中兩個日期的比較。

我的思路

這個題目的根本其實就是兩個時間的比較,這給我的第一個想法是常規做法(後面的《演算法筆記》思路會講到),後來寫到一半,突然想起了《演算法筆記》中對上面那個題目中兩個日期的比較方法:
正常讀入,然後用一個long long型變數 = year*10000+month*100+day; 這樣兩個日期比較就非常直接了~

這個明白了之後,此題就基本解決。但是第一次提交之後發現有一個點過不去,就想應該是邊界資料沒有過,後來測試了左右邊界,發現並不是這裡的問題,看了《演算法筆記》才發現邊界資料還存在一種情況,那就是所有輸入都不合法

,特判一下就可以了。

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

int main(){

    int n;
    int year,month,day;
    int count = 0;  //有效年齡個數
    char name[6], max_name[6], min_name[6];
    long long maxAge = 20140907, minAge = 18140905; 

    scanf("%d",&n);


    for(int i = 0; i < n; i++){

        scanf
("%s %d/%d/%d",&name,&year,&month,&day); //方便年齡比較 long long birth = year*10000+month*100+day; //過濾不合理日期 if(birth < 18140906 || birth > 20140906); else{ //得到最年長和最年輕的人 count++; if(birth < maxAge){ //得到最年長 strcpy(max_name,name); maxAge = birth; } if
(birth > minAge){ //得到最年輕 strcpy(min_name,name); minAge = birth; } } } if(count) printf("%d %s %s\n",count,max_name,min_name); else printf("0\n"); return 0; }

演算法筆記思路

演算法筆記的思路就是用最常規的方法比較兩個日期的大小關係。

#include<stdio.h>

struct info{
    char name[10];
    int y,m,d;
}youngest,oldest,temp,left,right; //left & right 用來儲存兩個邊界 

bool lessEqu(info a, info b){ //if a's date <= b's date return true
    if(a.y != b.y) return a.y <= b.y;
    else if(a.m != b.m) return a.m <= b.m;
    else return a.d <= b.d;
}

bool moreEqu(info a, info b){ //if a's date >= b's date return true
    if(a.y != b.y) return a.y >= b.y;
    else if(a.m != b.m) return a.m >= b.m;
    else return a.d >= b.d;
}

void init(){
    right.y = oldest.y = 2014; left.y = youngest.y = 1814; //pay attention to oldest & youngest's year. 
    right.m = left.m = youngest.m = oldest.m = 9;
    right.d = left.d = youngest.d = oldest.d = 6;
} 

int main(){

    int n;
    int count = 0;
    scanf("%d",&n);

    init();

    for(int i = 0; i < n; i++){
        scanf("%s %d/%d/%d",temp.name,&temp.y,&temp.m,&temp.d);

        if(lessEqu(temp,right) && moreEqu(temp,left)){ //如果日期合法 
            count++;
            if(lessEqu(temp,oldest)){   //更新oldest 
                oldest = temp;  
            }
            if(moreEqu(temp,youngest)){ //更新youngest 
                youngest = temp;
            } 
        }
    }

    if(count)
        printf("%d %s %s\n",count,oldest.name,youngest.name);
    else 
        printf("0\n");
    return 0;
} 

在擼這段程式碼過程中,粗心以及邏輯上造成了一些錯誤,比如兩個時間比較的函式、oldest.y和youngest.y的初值、temp和left、right的關係,這些是比較容易出錯的。

記錄在這裡的目的是掌握時間比較的方法:
1. 先比年,年如果不相等,直接可以比較出
2. 年如果相等,則需要比月,月不等,則可以直接比較出
3. 月如果相等,則需要比天

總結

  1. 掌握並運用了常規的日期比較方法
  2. 掌握並運用了long long型的日期比較方法
  3. 掌握並運用了結構體的直接賦值(參考部落格