牛客编程入门130题–精选(一)
前言

以下题目来自牛客网的编程入门训练题库(<—),题库适合大一,大二学生,题目有难有易,主要偏向入门。
不过里面还是有很多不错的题目,节约时间,没时间刷完的同学可以点击以下OJ链接,以下题目是博主做完亲选出的题目。
有些题目提供多种解法,希望帮助到你。以下题目博主均用C语言解题,大家也可以模仿思路使用其他编程语言。

文章目录
- 牛客编程入门130题--精选(一)
- 前言
- 题目OJ链接
- 1.反向输出数字
- 2.你能活多少秒?
- 3.计算三角形的面积
- 4.计算球体体积
- 5.变种水仙花
- 6.判断元音还是辅音
- 7.判断三角形
- 8.二元一次方程
- 9.打印X
- 10.筛选法求素数
 
题目OJ链接
-  T19.反向输出数字 
-  T22.你能活多少秒 
-  T26.计算三角形的面积 
-  T27.计算球体体积 
-  T38.变种水仙花 
-  T46.判断原因还是辅音 
-  T51.判断三角形 
-  T53.二元一次方程 
-  T68.打印X 
-  T78.筛选法求素数 
1.反向输出数字
T19.反向输出数字
题目描述
将一个四位数,反向输出。
输出描述:
针对每组输入,反向输出对应四位数。
示例:
输入:
1234输出:
4321
思路一 – 递归思路:
例如:逆序打印1234可分为:打印个位4 + 逆序打印123
即先打印个位部分,再打印逆序打印除去个位的数字
参考代码:
#include <stdio.h>
void ReversePrint(int n)
{
	if(n > 9)//如果是两位数
    {
        printf("%d",n%10);
        ReversePrint(n / 10);
    }
    else
    {
        printf("%d",n);
    }
}
int main()
{
	int num = 0;
    while(~scanf("%d", &num))//针对多组测试用例
    {
        ReversePrint(num);
    }
	return 0;
}
思路二:
迭代思想(非递归,循环)
例如:1234,每次取出他的个位进行打印即可
而取出个位的操作:%10/10即可完成
#include<stdio.h>
int main()
{
	int n = 0;
	while (~scanf("%d", &n))
	{
		while (n)
		{
			printf("%d", n % 10);
			n /= 10;
		}
	}
	return 0;
}
2.你能活多少秒?
T22.你能活多少秒?
题目描述:
问题:一年约有 3.156×107 s,要求输入您的年龄,显示该年龄合多少秒。
数据范围: 0 < age < 200
输入描述:
一行,包括一个整数age。
输出描述:
一行,包含一个整数,输出年龄对应的秒数。
示例1
输入:
20输出:
631200000
思路:
年龄 * 3.156×107 s == 你一辈子活了多少秒
但是需要考虑的东西:
3.156×107 s怎么表示(浮点型的表示方法)
200岁的人活的秒数已经超过了
int范围,造成溢出,可参考整形家族
参考代码:
#include <stdio.h>
int main()
{
	long long k = 3.156E7;//long long类型,防止溢出
	int age = 0;
	scanf("%d", &age);
	printf("%lld", age*k);
	return 0;
}
3.计算三角形的面积
T26.计算三角形的面积
描述
根据给出的三角形3条边a, b, c,计算三角形的周长和面积。
数据范围: 0 < a,b,c≤100000
输入描述:
一行,三角形3条边(能构成三角形),中间用一个空格隔开。
输出描述:
一行,三角形周长和面积(保留两位小数),中间用一个空格隔开,输出具体格式详见输出样例。
示例1
输入:
3 3 3输出:
circumference=9.00 area=3.90
思路:
海伦公式(之前还以为这个公式是海伦推出来的)
可能你可以利用几何知识,求解直角三角形,等腰三角形的面积
但是仅仅知道三条边,利用几何知识是不够的,而大佬阿基米德帮我们推出了一个知道三条边即可计算面积的海伦公式。
公式非常便于记忆
参考代码:
#include <stdio.h>
#include<math.h>
int main()
{
	float a = 0.0f, b = 0.0f, c = 0.0f;
	float C = 0.0f, S = 0.0f, p = 0.0f;
	scanf("%f %f %f", &a, &b, &c);
	C = a + b + c;
	p = C / 2;
	S = sqrt(p*(p - a)*(p - b)*(p - c));//sqrt开平方函数,头文件math.h所包含
	printf("circumference=%.2f area=%.2f", C, S);
	return 0;
}
4.计算球体体积
T27.计算球体体积
描述
给定一个球体的半径,计算其体积。其中球体体积公式为 V = 4/3πr3,其中 π = 3.1415926。
数据范围:输入一个浮点值 0≤n≤15
输入描述:
一行,用浮点数表示的球体的半径。
输出描述:
一行,球体的体积,小数点后保留3位。
示例1
输入:
3.0输出:
113.097
思路:
按照公式来即可:但是需要注意的是如果使用
float类型去解这道题,会有精度丢失,造成题目过不了。
参考代码:
#include <stdio.h>
int main()
{
	const double pi = 3.1415926;
	double rad = 0.0;
	scanf("%lf", &rad);
	printf("%.3lf", 4.0 / 3.0 * pi * rad * rad * rad);
	return 0;
}
5.变种水仙花
T38.变种水仙花
描述
变种水仙花数 - Lily Number:把任意的数字,从中间拆分成两个数字,比如1461 可以拆分成(1和461),(14和61),(146和1),如果所有拆分后的乘积之和等于自身,则是一个Lily Number。
例如:
655 = 6 * 55 + 65 * 5
1461 = 1 * 461 + 14 * 61 + 146 *1
求出 5位数中的所有 Lily Number。
输入描述:
无
输出描述:
一行,5位数中的所有 Lily Number,每两个数之间间隔一个空格。
思路:
了解如何拆分数字
例如1461
第一部分拆分:146 1(按个位进行拆分)
第二部分拆分:14 61(按十位进行拆分)
第三部分拆分:1 461(按百位进行拆分)
直到进行拆分下去会造成其中一部分为0,则拆分完毕
方法一:(递归思路)
参考代码:
#include <stdio.h>
 
int LilyNumber(int num,int i)//使用变量i来控制递归
{
    if (num / i == 0)
    {
        return 0;
    }
    return LilyNumber(num, i * 10) + (num / i)*(num % i);//每部分拆分时,i*10达到个十百位拆分的效果
 
}
 
int main()
{
    for (int i = 10000; i <= 99999; ++i)
    {
        if (i == LilyNumber(i, 10))
        {
            printf("%d ", i);
        }
    }
    printf("\n");
    return 0;
}
为了不让同学们养成递归综合症,咱们也提供非递归解法
参考代码
#include <stdio.h>
int LilyNumber(int num)
{
	int sum = 0;
	int i = 10;
	while (num / i)
	{
		sum += ((num / i) * (num % i));
		i*=10;
	}
	return sum;
}
int main()
{
	for (int i = 10000; i <= 99999; ++i)
	{
		if (i == LilyNumber(i))
		{
			printf("%d ", i);
		}
	}
	printf("\n");
	return 0;
}
6.判断元音还是辅音
T46.判断原因还是辅音
描述
KiKi开始学习英文字母,BoBo老师告诉他,有五个字母A(a), E(e), I(i), O(o),U(u)称为元音,其他所有字母称为辅音,请帮他编写程序判断输入的字母是元音(Vowel)还是辅音(Consonant)。
输入描述:
多组输入,每行输入一个字母。
输出描述:
针对每组输入,输出为一行,如果输入字母是元音(包括大小写),输出“Vowel”,如果输入字母是非元音,输出“Consonant”。
示例1
输入:
A b输出:
Vowel Consonant
思路
如果是
aeiou或者AEIOU则是元音,否则是辅音注意:
- 题目要求指针多组输入。
- 多组输入字符时,一定要注意要在下次输入字符之前清空缓冲区。
例如:第一次输入字符:按A+回车(‘\n’),那么第二次输入字符,字符直接变成第一次输入时的回车(‘\n’)了
为了让代码显得更清晰,咱们使用函数实现单独的功能
参考代码
#include <stdio.h>
#include<stdbool.h>
bool det_vowel(char ch)
{
	char vowel[10] = "aoeiuAOEIU";
	for (int i = 0; i < 10; ++i)
	{
		if (ch == vowel[i])
		{
			return true;
		}
	}
	return false;
}
int main()
{
	char ch = 0;
	while ((scanf("%c",&ch)) != EOF)
	{
		if (det_vowel(ch))
		{
			printf("Vowel\n");
		}
		else
		{
			printf("Consonant\n");
		}
		getchar();//吃掉\n
	}
	return 0;
}
7.判断三角形
T51.判断三角形
描述
KiKi想知道已经给出的三条边a,b,c能否构成三角形,如果能构成三角形,判断三角形的类型(等边三角形、等腰三角形或普通三角形)。
输入描述:
题目有多组输入数据,每一行输入三个a,b,c(0<a,b,c<1000),作为三角形的三个边,用空格分隔。
输出描述:
针对每组输入数据,输出占一行,如果能构成三角形,等边三角形则输出“Equilateral triangle!”,等腰三角形则输出“Isosceles triangle!”,其余的三角形则输出“Ordinary triangle!”,反之输出“Not a triangle!”。
示例1
输入:
2 3 2 3 3 3输出:
Isosceles triangle! Equilateral triangle!
思路:
- 先判断是否能组成三角形 – 两边之和大于第三边
- 再判断是否为等腰三角形 – 任意两边相等
- 再判断是否为等边 – 三遍相等
为了让代码显得更清晰,咱们使用函数来实现判断三角形的功能,并且合理利用函数的返回值,达到方法一的效果
方法一:-- 玩的有点花
参考代码:
#include <stdio.h>
char is_triangle(int a, int b, int c)
{
	//1.c中放最大边,a,b中放两小边
	if (c < a)
	{
		int tmp = c;
		c = a;
		a = tmp;
	}
	if (c < b)
	{
		int tmp = c;
		c = b;
		b = tmp;
	}
	if (a + b > c)//是普通三角形的情况下
	{
		if (a == b || a == c || b == c)//等腰三角形的情况下
		{
			if (a == b && a ==c)//等边三角形的情况下
			{
				return 'E';
			}
				return 'I';
		}
		//普通三角形
		return 'O';
	}
	else
	{
		return 'N';
	}
}
int main()
{
	int a = 0, b = 0, c = 0;
	char ret = 0;
	while ((scanf("%d %d %d", &a, &b, &c)) != EOF)
	{
		ret = is_triangle(a, b, c);
		if (ret == 'O')
		{
			printf("Ordinary triangle!\n");
		}
		else if (ret == 'I')
		{
			printf("Isosceles triangle!\n");
		}
		else if (ret == 'E')
		{
			printf("Equilateral triangle!\n");
		}
		else if (ret == 'N')
		{
			printf("Not a triangle!\n");
		}
	}
	return 0;
}
方法二 – 穷举法(直截了当)(因为只有三条边,量上比较简洁)
#include<stdio.h>
int main()
{
    int a = 0;
    int b = 0;
    int c = 0;
    while(scanf("%d %d %d", &a, &b, &c) != EOF)
   {
        //满足条件就是三角形
        if(a+b>c && b+c>a && c+a>b)
       {
            if(a==b && b==c)
                printf("Equilateral triangle!\n");
            else if((a==b &&a!=c) || (a==c && a!=b) || (b==c &&b!=a))
                printf("Isosceles triangle!\n");
            else
                printf("Ordinary triangle!\n");
       }
        else
            printf("Not a triangle!\n");
   }
    return 0;
}
8.二元一次方程
T53.二元一次方程
描述
从键盘输入a, b, c的值,编程计算并输出一元二次方程ax2 + bx + c = 0的根,当a = 0时,输出“Not quadratic equation”,当a ≠ 0时,根据△ = b2 - 4ac的三种情况计算并输出方程的根。
输入描述:
多组输入,一行,包含三个浮点数a, b, c,以一个空格分隔,表示一元二次方程ax2 + bx + c = 0的系数。
输出描述:
针对每组输入,输出一行,输出一元二次方程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
输入:
2.0 7.0 1.0输出:
x1=-3.35;x2=-0.15
示例2
输入:
0.0 3.0 3.0输出:
Not quadratic equation
示例3
输入:
1 2 1输出:
x1=x2=-1.00
示例4
输入:
2 2 5输出:
x1=-0.50-1.50i;x2=-0.50+1.50i
示例5
输入:
1 0 1输出:
x1=0.00-1.00i;x2=0.00+1.00i
思路:
高中数学知识:二元一次方程–公式法
需要注意:浮点数是如何判断>0 ==0 <0的,因为浮点数有一个表示范围,并不是可以准确表示一个小数的
没有太多技巧,考的就是一个细心
浮点数的表示范围图:

参考代码
#define  BOUNDARY 1e-7//下溢
#include<stdio.h>
#include<math.h>
//计算判别式--disc
int cal_disc(double a, double b, double c)
{
	return (b*b) - 4 * a*c;
}
//计算方程
//这里有个VS快捷键,刚发现,就分享在这里吧
//将选中的代码全部大写---ctrl + shift +  u
//将选中的代码全部小写--ctrl + u
int main()
{
	double a = 0, b = 0, c = 0;
	double disc = 0.0;//接收判别式的值
	while ((scanf("%lf %lf %lf", &a, &b, &c)) != EOF)//多组输入
	{
		if (a >= -BOUNDARY && a <= BOUNDARY)//a = 0的情况,不是二元一次方程
		{
            printf("Not quadratic equation\n");
			continue;//直接下一步
		}
		disc = cal_disc(a, b, c);
		if (disc > BOUNDARY)//disc > 0 -- 两个不同的实数根
		{
			double prev = -b / (2 * a);
			double next = sqrt(disc) / (2 * a);
			printf("x1=%.2f;x2=%.2f\n", prev - next, prev + next);
		}
		else if (disc < -BOUNDARY)//disc < 0 -- 两个不同的复数根
		{
			double real = -b / (2 * a);
			double imag = sqrt(-disc) / (2 * a);
			printf("x1=%.2f-%.2fi;x2=%.2f+%.2fi\n", real, imag, real, imag);
		}
		else//disc == 0 --- 两个相同的实数根
		{
			double x = -b / (2 * a);
			if (x >= -BOUNDARY && x <= BOUNDARY)//等于0时
			{
				x = fabs(x);
			}
			printf("x1=x2=%.2f\n", x);
		}
	}
	return 0;
}
9.打印X
T68.打印X
描述
KiKi学习了循环,BoBo老师给他出了一系列打印图案的练习,该任务是打印用“*”组成的X形图案。
输入描述:
多组输入,一个整数(2~20),表示输出的行数,也表示组成“X”的反斜线和正斜线的长度。
输出描述:
针对每行输入,输出用“*”组成的X形图案。
示例1
输入:
5输出:
* * * * * * * * *
示例2
输入:
6复制
输出:
* * * * ** ** * * * *
思路
这个题目分享出来的原因是:如果思路不对,那么很容易卡住,当时博主就是使用其他办法,想了半天也没达到打印题目图案的效果
如果思路正确,其实非常简单。大家有其他方法,也可以分享
想象成一个正方形,就在主对角线和副对角线打印*,即可达到效果。
参考代码:
#include <stdio.h>
int main()
{
	int n = 0;
	while ((scanf("%d", &n)) != EOF){
		for (int i = 0; i < n; ++i)
		{
			for (int j = 0; j < n; ++j)
			{
				if (i == j)//主对角线打印*
				{
					printf("*");
				}
				else if (i + j == n - 1)//副对角线打印*
				{
					printf("*");
				}
				else
				{
					printf(" ");//其他位置打印空格
				}
			}
			printf("\n");
		}
	}
	return 0;
}
10.筛选法求素数
T78.筛选法求素数
求解素数存在n种境界
想必大家都了解过试除法求素数
而这个题目要求的是使用筛选法,让我们一起来学习筛选法吧
描述
用筛选法求n以内的素数。筛选法求解过程为:将2~n之间的正整数放在数组内存储,将数组中2之后的所有能被2整除的数清0,再将3之后的所有能被3整除的数清0 ,以此类推,直到n为止。数组中不为0 的数即为素数。
输入描述:
多组输入,每行输入一个正整数(不大于100)。
输出描述:
针对每行输入的整数n,输出两行,第一行,输出n之内(包括n)的素数,用空格分隔,
第二行,输出数组中2之后被清0 的个数。每行输出后换行。
示例1
输入:
20输出:
2 3 5 7 11 13 17 19
思路:
相比于试除法:消耗空间换取时间的手段
思路:将那些不是素数的筛选掉,是素数的筛选出来
素数:能被2~n整除的数字
参考代码
#include <stdio.h>
int main()
{
    int n = 0;
    while(~scanf("%d",&n))
    {
        //1.将2~n这些数字放进数组中存储
        int arr[n];
        arr[0] = 0;
        for(int i = 1;i<n;++i)
        {
            arr[i] = i + 1;
        }
        //2.遍历数组
        for(int i = 1;i<n;++i)
        {
            if(arr[i] == 0)//如果没有这句代码,当arr[i]==0就出现bug了
            {
                continue;
            }
            //所有i后面能被i整除的数字都清0
            for(int j = i + 1;j<n;++j)
            {
                if(arr[j] % arr[i] == 0)
                {
                    arr[j] = 0;
                }
            }
        }
        //3.打印不为0的数
        for(int i = 0;i<n;++i)
        {
            if(arr[i] != 0)
            {
                printf("%d ",arr[i]);
            }
        }
        printf("\n");
    }
    return 0;
}
刷题是很有必要的,对我们的代码能力和逻辑能力都有一定的帮助。但是也要量力而行,选择适合自己的题目难度,题目数量,每天刷个几道,最后一定会量变到质变的,加油!!!






















