C语言牛客网经典练习——简单但通过率低的题目

前言

  • 在学习C语言知识的过程中刷题是很重要的,俗话说眼看千遍不如手动一遍
  • 因为在真正动手去刷题的时候会暴露出更多你没有意识到的问题
  • 接下来我就为各位奉上几道我认为比较有代表性的题

1.分支控制——计算一元二次方程

1.1题目描述

  • 从键盘输入a, b, c 的值,编程计算并输出一元二次方程 ax2 + bx + c = 0 的根,当 a = 0 时,输出**“Not quadratic equation”**,当 a ≠ 0 时,根据 △ = b2 - 4ac 的三种情况计算并输出方程的根

1.2输入描述

  • 多组输入,一行,包含三个浮点数 a, b, c,
  • 以一个空格分隔,表示一元二次方程 ax2 + bx + c = 0 的系数。

1.3输出描述

  • 针对每组输入,输出一行,输出一元二次方程 ax2 + bx +c = 0 的根的情况。
  • 如果 a = 0 ,输出 “Not quadratic equation”
  • 如果 a ≠ 0 ,分三种情况:
    △ = 0,则两个实根相等,输出形式为:x1=x2=…。
    △ > 0,则两个实根不等,输出形式为:x1=…;x2=…,其中x1 <= x2。
    △ < 0,则有两个虚根,则输出:x1=实部-虚部i;x2=实部+虚部i,即x1的虚部系数小于等于x2的虚部系数,实部为0时不可省略。实部= -b / (2*a),虚部= sqrt(-△ ) / (2*a)
  • 所有实数部分要求精确到小数点后 2 位,数字、符号之间没有空格。

1.4示例

在这里插入图片描述

1.5代码实现

  • 这里主要是利用多分支来讨论每种情况
  • 计算一元二次方程的根的公式为

在这里插入图片描述

  • 如果△小于零的话,把上面的4ac和b方的位置换一下,然后在根号后加个 i 就表示根为虚数了
  • 接下来具体看一下代码
#include <stdio.h>
#include <math.h>
int main() {
    double a = 0.0;
    double b = 0.0;
    double c = 0.0;
    while (scanf("%lf %lf %lf", &a, &b, &c) != EOF)
    {
        if (a == 0)
        {
            printf("Not quadratic equation\n");
        }
        else
        {
            int derta = b * b - 4 * a * c;
            if (derta == 0)
            {
                if (-b / (2.0 * a) != 0)
                {
                    printf("x1=x2=%.2lf", -b / (2.0 * a));
                }
                else
                {
                    printf("x1=x2=0.00");
                }
            }
            else if (derta > 0)
            {
                printf("x1=%.2lf;", ((-b - sqrt(derta)) / (2.0 * a)));
                printf("x2=%.2lf", ((-b + sqrt(derta)) / (2.0 * a)));
            }
            else
            {
                printf("x1=%.2lf-%.2lfi;", -b / (2.0 * a), sqrt(-derta) / (2.0 * a));
                printf("x2=%.2lf+%.2lfi", -b / (2.0 * a), sqrt(-derta) / (2.0 * a));
            }
        }
        printf("\n");
    }

    return 0;
}

  • 我在编写代码的时候犯了两个错误,
  • 第一个是没有看清题目所要求的 “多组输入”
  • 第二个是在运算顺序上,

在这里插入图片描述

  • 当时我没有在这些地方加上小括号,导致运算的顺序变成了先除2,再乘 a ,导致最后一直没有通过
  • 如果这里不加小括号的话,可以把“ * ” 换成 “ / ”,也是可以的

2. 循环结构——水仙花数

2.1 描述

  • 春天是鲜花的季节,水仙花就是其中最迷人的代表,数学上有个水仙花数,他是这样定义的: “水仙花数”是指一个三位数,它的各位数字的立方和等于其本身,比如:153=13+53+3^3。 现在要求输出所有在m和n范围内的水仙花数。

2.2输入描述

  • 输入数据有多组,每组占一行,包括两个整数m和n(100 ≤ m ≤ n ≤ 999)。

2.3输出描述

  • 对于每个测试实例,要求输出所有在给定范围内的水仙花数,就是说,输出的水仙花数必须大于等于m,并且小于等于n,如果有多个,则要求从小到大排列在一行内输出,之间用一个空格隔开; 如果给定的范围内不存在水仙花数,则输出no; 每个测试实例的输出占一行。

2.4示例

在这里插入图片描述

2.5代码编写

  • 水仙花数是很经典的题了,难度并不大,
  • 主要是怎么样可以把一个三位数的每一位都取出来,还有就是如何判断在给定的范围里有没有水仙花数
#include <stdio.h>

int main() 
{
    int m, n;
    int a, b, c;
    while (scanf("%d %d", &m, &n) != EOF) 
    { 
        int flag = 0;
        for (int i=m; i<=n; i++)
        {
            a = i / 100;
            b = i / 10 %10; 
            c = i % 10;
            if (a*a*a + b*b*b + c*c*c == i)
            {
                printf("%d ", i);
                flag = 1;
            }
        }
        if (flag == 0)
        {
            printf("no\n");
        }
    }
    return 0;
}
  • 这里引入了一个 flag 变量来判断是否在对应范围有水仙数,并且在每次输入的时候,flag 都要重新赋值为 0
  • 这题的通过率只有百分之 10 多一点

在这里插入图片描述

  • 但是通过上面的解释会发现并不难

3. 输出格式和运算——小乐乐定闹钟

3.1 描述

  • 小乐乐比较懒惰,他现在想睡觉,然后再去学习。他知道现在的时刻,以及自己要睡的时长,想设定一个闹钟叫他起床学习,但是他太笨了,不知道应该把闹钟设定在哪个时刻,请你帮助他。(只考虑时和分,不考虑日期)

3.2输入描述

  • 输入现在的时刻以及要睡的时长k(单位:minute),中间用空格分开。
  • 输入格式:hour:minute k(如 hourminute 的值为 1 ,输入为1,而不是01)
  • (0 ≤ hour ≤ 23,0 ≤ minute ≤ 59,1 ≤ k ≤ 109)

3.3输出描述

  • 对于每组输入,输出闹钟应该设定的时刻,输出格式为标准时刻表示法(即时和分都是由两位表示,位数不够用前导0补齐)。

3.4示例

在这里插入图片描述

3.5代码实现

  • 这里要有两个地方需要注意一下
  • 首先是输出的格式,小时和分钟都需要输出两位数,不足前面自动补零
  • 其次是计算小时的时候会不会出现大于 24 的情况
#include<stdio.h>
int main(void)
{
    int hour,min,howmin;
    scanf("%d:%d %d",&hour,&min,&howmin);//按照格式输入三个数
    hour=(hour+(howmin+min)/60)%24;//计算小时,因为不考虑日期,所以先计算得到总共多少小时,再对24取余,以防出现大于24的情况
    min=(howmin+min)%60;//看剩下多少分钟
    printf("%02d:%02d",hour,min);
    return 0;
}
  • 在输出格式里,
  • printf(“%2d”, hour),是输出两位数字,不足自动补空格
  • printf(“%02d”, hour), 是把自动补空格变成了自动补 0

最后,
如果上述代码或表述有问题,
欢迎一起交流。

  • 31
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

看落日的YT

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值