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. 掌握并运用了结构体的直接赋值(参考博客
  • 16
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 19
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 19
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值