写点什么

每日算法刷题 Day3- 起始时间转换、二次方根、while 连续输入、斐波那契思路

作者:timerring
  • 2022 年 9 月 29 日
    山东
  • 本文字数:1898 字

    阅读完需:约 6 分钟

⭐每日算法题解系列文章旨在精选重点与易错的算法题,总结常见的算法思路与可能出现的错误,与笔者另一系列文章有所区别,并不是以知识点的形式提升算法能力,而是以实战习题的形式理解算法,使用算法。

8.游戏时间 2

读取四个整数 A,B,C,D,用来表示游戏的开始时间和结束时间。


其中 A 和 B 为开始时刻的小时和分钟数,C 和 D 为结束时刻的小时和分钟数。


请你计算游戏的持续时间。


比赛最短持续 1 分钟,最长持续 24 小时。

输入格式

共一行,包含四个整数 A,B,C,D。

输出格式

输出格式为 O JOGO DUROU X HORA(S) E Y MINUTO(S),表示游戏共持续了 X 小时 Y 分钟。

数据范围

0≤A,C≤230≤B,D≤59

输入/出样例

输入样例 1:


7 8 9 10
复制代码


输出样例 1:


O JOGO DUROU 2 HORA(S) E 2 MINUTO(S)
复制代码


输入样例 2:


7 7 7 7
复制代码


输出样例 2:


O JOGO DUROU 24 HORA(S) E 0 MINUTO(S)
复制代码


输入样例 3:


7 10 8 9
复制代码


输出样例 3:


O JOGO DUROU 0 HORA(S) E 59 MINUTO(S)
复制代码

代码

思路 1:全部转换为分钟计算起始和结束时间,这样方便计算,当计算 spent 时间小于 0 时,加上一整天的时间数 1440 即可。最后输出时采用 spent_time / 60 计算小时数,spent_time % 60 计算分钟数。


#include <cstdio>
int main(){ int a, b, c, d; scanf("%d%d%d%d", &a, &b, &c, &d);
int start = a * 60 + b; int end = c * 60 + d;
int spent_time = end - start; if (spent_time <= 0) spent_time += 1440;
printf("O JOGO DUROU %d HORA(S) E %d MINUTO(S)", spent_time / 60, spent_time % 60);
return 0;}
复制代码


思路 2:将借位的方式处理一下,总体思路还是 c-a 计算小时,d-b 计算分钟。


#include <iostream>
using namespace std;
int main(){ int a, b, c, d; cin >> a >> b >> c >> d;
if(d < b) c -= 1,d += 60; // 分钟数不够减,借小时,补60分钟
if(c < a) c += 24;
if(c == a && d == b) c += 24; // 特判,这种情况表示过了一天
printf("O JOGO DUROU %d HORA(S) E %d MINUTO(S)",c-a,d-b);}
复制代码

反思

#include <bits/stdc++.h>using namespace std;int main(){    int a,b,c,d;    cin>>a>>b>>c>>d;    if(a==c)    {        if(d>b)printf("O JOGO DUROU %d HORA(S) E %d MINUTO(S)",c-a,d-b);        else if(d<b)printf("O JOGO DUROU %d HORA(S) E %d MINUTO(S)",c-a-1+24,d+60-b);        else cout<<"O JOGO DUROU 24 HORA(S) E 0 MINUTO(S)";    }    else if(c>a)    {        if(d>=b)printf("O JOGO DUROU %d HORA(S) E %d MINUTO(S)",c-a,d-b);        else if(d<b)printf("O JOGO DUROU %d HORA(S) E %d MINUTO(S)",c-a-1,d+60-b);    }    else if(c<a)    {        if(d>=b)printf("O JOGO DUROU %d HORA(S) E %d MINUTO(S)",c-a+24,d-b);        else if(d<b)printf("O JOGO DUROU %d HORA(S) E %d MINUTO(S)",c-a-1+24,d+60-b);    }    return 0;}
复制代码


做法太过于冗余,观察可知 c>a 和 c<a 输出的逻辑差别不大,可以进一步统一,直接对变量进行自增减,输出采用同一语句,以达到化简的目的。

9.求解二次方根

总结


在求解二次方根的公式中,


(-b-sqrt(b*b-4*a*c))/2*a
复制代码


有问题,注意括号问题,改为:


(-b-sqrt(b*b-4*a*c))/(2*a)
复制代码

10. 连续整数相加

如果读入的 N 为 0 或负数,则继续读取数字直至读入 N 值为正整数为止。


可以将式子由


    while(n<=0){        cin>>n;    }
复制代码


化简到


while(cin>>n,n<=0);
复制代码

11. 区间 2

第一行包含整数 N,表示共有 N 个整数需要进行判断。


接下来 N 行,每行包含一个整数 Xi。


   int n;    cin >> n;    while(n--)
复制代码



for(int i = 0;i<n;i++)
复制代码


更加简便。

12. 简单斐波那契

以下数列 0 1 1 2 3 5 8 13 21 ... 被称为斐波纳契数列。


这个数列从第 3 项开始,每一项都等于前两项之和。


输入一个整数 N,请你输出这个序列的前 N 项。

输入格式

一个整数 N。

输出格式

在一行中输出斐波那契数列的前 N 项,数字之间用空格隔开。

数据范围

0<N<46

输入样例:

5
复制代码

输出样例:

0 1 1 2 3
复制代码

代码

#include<bits/stdc++.h>using namespace std;int main(){    int n,a[46]={0,1};    cin>>n;    for(int i=2;i<n;i++){    a[i]=a[i-1]+a[i-2];    }    for(int i = 0;i<n;i++)    {        cout<<a[i]<<" ";    }        return 0;}
复制代码


开数组过于浪费空间,并且多个循环效率不高。


一般斐波那契的不开数组思路如下:


#include<stdio.h>long long n,a,b=1,c;int main(){    scanf("%d",&n);    while(n--){        printf("%d ",a);        c=a+b;        a=b;        b=c;    }}
复制代码


其中 a=b,b=c,c=a+b 是一个整体左移的思想。




专题往期合集:每日算法题解

发布于: 刚刚阅读数: 3
用户头像

timerring

关注

还未添加个人签名 2022.07.14 加入

还未添加个人简介

评论

发布
暂无评论
每日算法刷题Day3-起始时间转换、二次方根、while连续输入、斐波那契思路_刷题_timerring_InfoQ写作社区