C语言MOOC编程练习:时间换算

C语言MOOC编程练习:时间换算

题目内容

UTC是世界协调时,BJT是北京时间,UTC时间相当于BJT减去8。现在,你的程序要读入一个整数,表示BJT的时和分。整数的个位和十位表示分,百位和千位表示小时。如果小时小于10,则没有千位部分;如果小时是0,则没有百位部分;如果小时不是0而分小于10分,需要保留十位上的0;如果小时是0而分小于10分的,则不需要保留十位上的0。如1124表示11点24分,而905表示9点5分,36表示0点36分,7表示0点7分。

有效的输入范围是0到2359,即你的程序不可能从测试服务器读到0到2359以外的输入数据。

你的程序要输出这个时间对应的UTC时间,输出的格式和输入的相同,即输出一个整数,表示UTC的时和分。整数的个位和十位表示分,百位和千位表示小时。如果小时小于10,则没有千位部分;如果小时是0,则没有百位部分;如果小时不是0而分小于10分,需要保留十位上的0;如果小时是0而分小于10分的,则不需要保留十位上的0。

提醒:要小心跨日的换算。

想法

首先大概理解换算逻辑,BJT = UTC + 8, 即UTC可由北京时间减去8小时得到。

解析数据

然后要解决的是如何解析给定的北京时间。输入的数据是以十进制整数来描述时间的。这种数据结构一般不具有算数意义,换言之,就是把字符直接储存在了数字里。所以我们要对其进行解析,是之成为可运算的格式。

那么如何解析呢?题目中说

如果小时是0,则没有百位部分;如果小时不是0而分小于10分,需要保留十位上的0;如果小时是0而分小于10分的,则不需要保留十位上的0。

看到这里应该感到雀跃,因为发现格式中没有多余的占位0。比如7:00只需写成700而不用写成0700.这给我们带来的好处是,它是可以作为数字被运算符操作的

不难发现分钟是不用转换的,而且分钟值在数值上就等于所给十进制整数的十位和个位数字。所以我们可以通过带余除法直接解析出分钟。设给出的数字是 t t t的话,我们可以得到以下关系
t = 100 × q + m i n , q ∈ Z , 0 ⩽ m i n < 100 t = 100 \times q + min,q\in\mathbb{Z},0\leqslant min<100 t=100×q+min,qZ,0min<100
实际上题目告诉我们上式中的 m i n min min一定满足 0 ⩽ m i n < 60 0 \leqslant min < 60 0min<60.更加巧合的是,式中的 q q q在数值上也恰好等于小时.于是式子可以写成更好看的形式:
t = 100 × h o u r + m i n , 0 ⩽ m i n < 60 t = 100 \times hour + min,0 \leqslant min < 60 t=100×hour+min,0min<60
注意这个式子的结论很好,因为我们可以把 t t t作为一个纯粹的数字而非具有意义的时刻并通过数学运算得到我们需要的结果,这对编程来说是非常友好的。

至此我们已经完成了对数据的解析。

换算

在BJT 8:00~24:00范围内的换算是没有任何难度的,直接将BJT的小时值减去8并保留分钟值就可以得到对应的UTC. 关键在于小时是不允许,也不会出现负数的,在0:00 ~ 7:59这一时段内,是不能直接减去8的.尽管如此,我们知道时刻虽然不能与群 { R , + } \{R,+\} {R,+}构成同构,却可以与模24同余的模加群同构.在这个群中,“-8”与“+16”具有相同的效果.所以对于0:00~7:59这一时段,我们可以用 h o u r U T C = h o u r B J T + 16 hour_{UTC} = hour_{BJT}+16 hourUTC=hourBJT+16来得到。

收尾

最后按照规定格式返回数据即可.

动手

Talk is cheap, show me the code.

#include <stdio.h>

int main(){
    int time;
    scanf("%d", &time);//输入样例并保存进变量time
    
    //按照分析进行解析
    int minute = time % 100;
    int hour = (time - minute) / 100;
    
    //进行换算
    if(hour - 8 < 0) 
    {
        (hour += 16);
    }
    else
    {
        (hour -= 8);
    }

    //构造输出结果并打印
    time = 100 * hour + minute;
    printf("%d", time);

    return 0;
}

上面的代码比较清晰地反映了这个算法的流程,唯一的缺点就是太啰嗦了,本人写练习的时候比较崇尚简洁,能省的变量就省,能写短点尽量写短(当然前提是本人能力范围之内【doge】)

比如上面这个 t i m e time time变量就丝毫没有存在的意义啊,他的活其实完全可以交给其他变量完成。还有这个奢侈的if-else,单句的直接换成3目啊。然后那个hour其实根本不用除以100,因为最后又乘回去了,为什么兜这个圈子呢。最后其实return 0也可以不写的【滑稽】,main()里面不写没啥大问题.于是有如下代码

#include <stdio.h>

int main(){
    int hour;
    scanf("%d", &hour);
    int minute = hour % 100;
    hour -= minute;
    hour - 800 < 0 ? (hour += 1600) : (hour -= 800);
    printf("%d", hour + minute);
}

嘿嘿嘿有没有一种三千预算进图吧的感觉。

  • 6
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值