经典例题(二)——超经典例题的归纳总结
目录
1、判断是不是字母
题目:判断输入的字符是不是字母。 输入描述: 多组输入,每一行输入一个字符。 输出描述 针对每组输入,输出单独占一行,判断输入字符是否为字母,如果是,输出 _is an alphabet.如果不是,输出:_is not an alphabet.
这道题看到后其实很好入手,字母也就是A-Z,a-z,直接入手即可,看如下代码:
#include <stdio.h>
int main()
{
char letter = 0;
while ((scanf("%c",&letter) != EOF))
{
if ((letter >= 'A' && letter <= 'Z') || (letter >= 'a' && letter <= 'z'))
{
printf("%c is an alphabet.\n", letter);
}
else
{
printf("%c is not an alphabet.\n", letter);
}
//gerchar清理掉\n
getchar();
}
return 0;
}
这里有一点需要注意,就是题目要求是每行输入一个字符,而我们使用scanf,其实当我们输入一个字符的时候,scanf还读取到了\n,即换行,就是我们每次输入一个字符后,还按下了Enter,也就是换行,所以其实我们输入的内容是一个字符+一个\n,所以我们在循环的内容里加上了getchar(),用来吸收\n,每次对一个字符进行判断完后,getchar()都会吸收剩下的\n。
2、斐波那契数列
题目:编程实现求第n个斐波那契数 例如:输入:5 输出:5 输入:10, 输出:55 输入:2, 输出:1
做这个题首先要知道什么是斐波那契数列,如下图:
看到这个,我们有两种思路,其中一种就是递归Fib(n)=Fib(n-2)+Fib(n-1)。 方法一:递归
#include<stdio.h>
int Fib(int n)
{
if (n <= 2)
return 1;
else
return Fib(n - 1) + Fib(n - 2);
}
int main()
{
int n = 0;
scanf("%d", &n);
int ret = Fib(n);
printf("%d", ret);
return 0;
}
这种方法虽然很容易想到,但是存在一个弊端,就是运算量太大了,看如下图:
大家可以看到,当我i们求第55项时,程序已经陷入死循环,卡在这里了。这便是它的缺陷,大家看另一种方法。 方法二、非递归 假如要求第五项,我们直接从前面加到第五项,即我们从第一项开始正着推 第一项:1 第二项:1 第三项:1+1=2 第四项:2+1=3 第五项:3+2=5
运算量大大减少,具体用代码如何实现呢?如下:
#include<stdio.h>
int Fib(int n)
{
int a = 1;
int b = 1;
int c = 1;
//前两项都是1
while (n > 2)
{
//Fib(3)=Fib(1)+Fib(2)
c = a + b;
//此时把Fib(2)赋值给a,把Fib(3)赋值给b,再次循环求Fib(4)......
a = b;
b = c;
n--;
}
return c;
}
int main()
{
int n = 0;
scanf("%d", &n);
int ret = Fib(n);
printf("%d", ret);
return 0;
}
而这时,我们求第55项就会减少大量运算
3、冒泡排序
题目:实现一个对整形数组的冒泡排序(升)
冒泡排序,首先我们要直到冒泡排序的核心思想:两两相邻元素进行比较。 那么具体是如何实现的呢?举个例子: 假如我们要对5 4 3 2 1,进行冒泡排序
了解这个后我们开始入手写代码:
#include<stdio.h>
int main()
{
int arr[] = { 2,7,6,6,6,0,8,2,8,2 };
//元素个数
int sz = sizeof(arr) / sizeof(arr[0]);
int left = 0;
int t = 0;
//趟数=元素个数-1
for (t = 0; t < sz - 1; t++)
{
//排序次数
int j = 0;
for (j = 0; j < sz - 1 - t; j++)
{
//两两排序
if (arr[j] > arr[j + 1])
{
int tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
}
}
}
//打印排序后的
int i = 0;
for (i = 0; i < sz - 1; i++)
{
printf("%d ", arr[i]);
}
return 0;
}
大家来看结果:
核心思想:相邻元素两两排序
4、序列中删除指定数字
有一个整数序列(可能有重复的整数),现删除指定的某一个整数,输出删除指定数字之后的序列,序列中未被删除数字的前后位置没有发生改变。 数据范围:序列长度和序列中的值都满足1≤n≤50 输入描述: 第一行输入一个整数(0≤N≤50)。 第二行输入N个整数,输入用空格分隔的N个整数。 第三行输入想要进行删除的一个整数。 输出描述: 输出为一行,删除指定数字之后的序列。
这里我们注意到,序列长度和序列中的值都满足1≤n≤50,那我们可以将删除的数赋值为0,然后打印时遇到0直接跳过,就好象这样:
具体实现代码如下:
#include<stdio.h>
int main()
{
int n = 0;
scanf("%d", &n);
int arr[50];
int i = 0;
for (i = 0; i < n; i++)
{
scanf("%d ", &arr[i]);
}
//要删除的整数
int del = 0;
scanf("%d", &del);
for (i = 0; i < n; i++)
{
if (arr[i] == del)
//赋值
arr[i] = 0;
}
for (i = 0; i < n; i++) //打印
{
//arr[i]==0的时候,表达式为假,不执行打印
if (arr[i])
{
printf("%d ", arr[i]);
}
}
return 0;
}
5、打印水仙花数
求出0~100000之间的所有“水仙花数”并输出。 “水仙花数”是指一个n位数,其各位数字的n次方之和确好等于该数本身,如:153=1^3 + 53+33,则153是一个“水仙花数”。
其实真正的水仙花数是三位数,这里我们根据题目的要求来做题就行。
首先,我们要确定这是一个几位数,然后把这个数拆分开来,再来求n次方之和,与这个数相比较,如果相等,就满足题目中的水仙花数要求。 代码如下:
#include<stdio.h>
#include<math.h>
void print_daffodil()
{
int i = 0;
//用来计算i是n位数,n>=1
for (i = 1; i <= 100000; i++)
{
int count = 1;
int sum = 0;
//将i的值赋值给tmp,计算是n位数
int tmp = i;
while (tmp/10)
{
count++;
tmp /= 10;
}
//将i的值再次赋值给tmp,用来计算个、十、百、千......位的n次方之和
tmp = i;
while (tmp)
{
int set = tmp % 10;
sum += (int)pow(set, count);
tmp /= 10;
}
//进行判断
if (sum == i)
{
printf("%d ", i);
}
}
}
int main()
{
print_daffodil();
return 0;
}
运行结果如下:
这里用到了库函数pow(a,b),求a的b次方,包含头文件<math.h>,返回值为double,这里我们用(int),强制类型转换为int。(因为我们所求的都是整数,所以结果不会有偏差)
6、变种水仙花数
变种水仙花数 - Lily Number:把任意的数字,从中间拆分成两个数字,比如1461 可以拆分成(1和461),(14和61),(146和1),如果所有拆分后的乘积之和等于自身,则是一个Lily Number。 例如: 655 = 6 * 55 + 65 * 5 1461 = 1461 + 1461 + 146*1 求出 5位数中的所有 Lily Number。 输入描述: 无 输出描述: 一行,5位数中的所有 Lily Number,每两个数之间间隔一个空格。
上一题的变形版本,首先还是需要求的这个数是几位数,然后再计算并判断,理解了上一题,这题就很简单了
代码如下:
#include<stdio.h>
#include<math.h>
int main()
{
int i = 0;
for (i = 10000; i <= 100000; i++)
{
int sum = 0;
//(%10)^(位数-1)* (/10)^(位数-1),进行求和
int count = 0;
int tmp = i;
while (tmp /= 10)
{
count++;
}
tmp = i;
while (count)
{
int set = pow(10, count);
int m = (tmp % set)* (tmp / set);
sum += m;
count--;
}
if (sum == i)
{
printf("%d ", i);
}
}
return 0;
}
7、有序序列判断
输入一个整数序列,判断是否是有序序列,有序,指序列中的整数从小到大排序或者从大到小排序(相同元素也视为有序)。 数据范围: 3≤n≤50 序列中的值都满足1≤val≤100 输入描述: 第一行输入一个整数N(3≤N≤50)。 第二行输入N个整数,用空格分隔N个整数。 输出描述: 输出为一行,如果序列有序输出sorted,否则输出unsorted。
思路:将序列的后一个数与前一个相比,无序即有大有小,否则就有序,而有大或者有小时各给flag1,flag2赋值1 只有两者同时为1时,表示有大有小,无序。否则有序
代码如下:
#include <stdio.h>
int main()
{
int arr[55] = { 0 };
int n = 0;
int flag1 = 0;
int flag2 = 0;
int i = 0;
scanf("%d", &n);
for (i = 0; i < n; i++)
{
scanf("%d", &arr[i]);
if (i > 0)
{
if (arr[i] < arr[i - 1])
{
flag1 = 1;
}
else if (arr[i] > arr[i - 1])
{
flag2 = 1;
}
}
}
if (flag1 && flag2)
printf("unsorted\n");//只有当flag1和flag2都为1的时候序列无序
else
printf("sorted\n");
return 0;
}
运行结果如下:
end
生活原本沉闷,但跑起来就会有风!诸君加油!!! 给个支持与鼓励吧,一起加油!❤
相关文章
- 在 Go 里用 CGO?这 7 个问题你要关注!
- 9款优秀的去中心化通讯软件 Matrix 的客户端
- 求职数据分析,项目经验该怎么写
- 在OKR中,我看到了数据驱动业务的未来
- 火山引擎云原生大数据在金融行业的实践
- OpenHarmony富设备移植指南(二)—从postmarketOS获取移植资源
- 《数据成熟度指数》报告:64%的企业领袖认为大多数员工“不懂数据”
- OpenHarmony 小型系统兼容性测试指南
- 肯睿中国(Cloudera):2023年企业数字战略三大趋势预测
- 适用于 Linux 的十大命令行游戏
- GNOME 截图工具的新旧截图方式
- System76 即将推出的 COSMIC 桌面正在酝酿大变化
- 2GB 内存 8GB 存储即可流畅运行,Windows 11 极致精简版系统 Tiny11 发布
- 迎接 ecode:一个即将推出的具有全新图形用户界面框架的现代、轻量级代码编辑器
- loongarch架构介绍(三)—地址翻译
- Go 语言怎么解决编译器错误“err is shadowed during return”?
- 敏捷:可能被开发人员遗忘的部分
- Denodo预测2023年数据管理和分析的未来
- 利用数据推动可持续发展
- 在 Vue3 中实现 React 原生 Hooks(useState、useEffect),深入理解 React Hooks 的