前情回顾:在4级的时候,我们学习了程序的流程控制
目录
关卡列表
你遇到的关卡如下:
第一关:输出100~1000之间的水仙花数
水仙花数是指一个三位数,它的每个数位上的数字的立方和等于它本身。例如,153 是一个水仙花数,因为
第二关:输出2~100之间的素数
素数是只能被 1 和自身整除的大于 1 的自然数。例如:2、3、5、7 、11 、13.......
第三关: 输出100~1000之间的回文数
回文数是指一个数字在正读和反读时都相同的数。例如,121 是一个回文数,因为从左到右读和从右到左读都是 121;再如,1331 也是回文数,无论正向还是反向读取,其数字排列都是一样的。
第四关:输入一个十进制整数数(0~15),再输出该数转二进制(限4位)的形式
例如:十进制数13转二进制为1101,将1101输出到打印台
第五关: 求斐波那契数列的第20列
斐波那契数列是指这样一个数列:0、1、1、2、3、5、8、13、21、34、…… ,根据斐波那契数列的规则 F(0)=0,F(1)=1,F(n)=F(n−1)+F(n−2)(n≥2,n∈N∗),可通过递推的方式算出第 20 项的值。
先自己尝试编写代码突破5个关卡,最好不要使用AI,通过自己思考解题是最爽的!可以回顾前面几级的知识,运用这些知识就可以解开这些题目。 当实在没思路的时候,可以查看下方的解法,多看多想,学好编程的第一步就是会看代码。
突破关卡
第一关解法
首先分析题目,如下:
解题步骤:
第1步:获得100~1000之间的所有数。由此可以使用for语句循环实现
for(int i=100;i<1000;i++)
{
}
那么每一次变量i就我们的操作数,后面都是循环体中对操作数进行对应的操作。
第2步:提取操作数i的百位、十位和个位。因此我们可以通过整除和取余实现。
int hundreds, tens, units; //用来存储百位、十位、个位
for(int i=100;i<1000;i++)
{
hundreds = i/100; //提取百位
tens = i/10%10; //提取十位
units = i%10; //提取个位
}
第3步:判断操作数i是否为水仙数。每位立方之后再相加是否等于操作数i,条件为真就将i输出
int hundreds, tens, units; //用来存储百位、十位、个位
for(int i=100;i<1000;i++)
{
hundreds = i/100; //提取百位
tens = i/10%10; //提取十位
units = i%10; //提取个位
if( i== (hundreds*hundreds*hundreds + tens*tens*tens + units*units*units ) ) //判断是否为水仙花数
printf("%d\t",i); //\t为空位符
}
第4步:整体运行。将这个代码逻辑放入主函数中运行,查看结果。
#include <stdio.h>
int main() {
int hundreds, tens, units; //用来存储百位、十位、个位
printf("100~1000之间的水仙花数有:");
for(int i=100;i<1000;i++)
{
hundreds = i/100; //提取百位
tens = i/10%10; //提取十位
units = i%10; //提取个位
if( i== (hundreds*hundreds*hundreds + tens*tens*tens + units*units*units ) ) //判断是否为水仙花数
printf("%d\t",i); //\t为空位符
}
return 0;
}
运行结果:
第二关解法
首先分析题目,如下:
解题步骤:
第1步:由于素数是大于1的自然数,所以要得到2~100之间的所有数,用for语句循环实现
int i; //存储操作数
for(i=2;i<100;i++)
{
}
那每一次我们的操作数就是i,后面也是围绕着i来做操作。
第2步: 寻找除了i自身,还有没有能整除i的数(整除的意思就是余数为0)。那我们需要再写一个for循环语句,用一个自增变量从2增到i,寻找2~i之间是否存在能整除i的数。
int i,j; //存储操作数
for(i=2;i<100;i++)
{
for(j=2;j<i;j++)
if(i%j == 0) break;
}
假设2~i之间存在能整除的数,就使用break跳出(break能跳出最近的循环),那么此时j的值就是此数了;再假设2~i之间并没有能整除的数,那么j会一直自增,直到j<i不成立,那么此时j的值等于i的值了。那么我们只需要判断j和i的值是否相等,就可以判断i是否为素数了。
第3步:判断i是否为素数,只需要判断j经过for语句后的值,是否与i相等即可。如果成立,则将i输出。
int i,j; //存储操作数
for(i=2;i<100;i++)
{
for(j=2;j<i;j++)
if(i%j == 0) break; //存在其他整除的数
if(j==i) //判断是否为素数
printf("%d\n",i);
}
这种使用了两个for循环的语句,也叫做双重循环。
第4步:整体运行。将这个代码逻辑放入主函数中运行,查看结果。
#include <stdio.h>
int main() {
int i,j; //存储操作数
printf("2~100之间的素数有:\n");
for(i=2;i<100;i++)
{
for(j=2;j<i;j++)
if(i%j == 0) break; //存在其他整除的数
if(j==i) //判断是否为素数
printf("%d\n",i);
}
return 0;
}
运行结果:
第三关解法
首先分析题目,如下:
解题步骤:
第1步:取得100~1000之间的所有数,用for语句循环实现
for(int i=100;i<1000;i++)
{
}
那每一次我们的操作数就是i,后面也是围绕着i来做操作。
第2步:将操作数i反过来,也就是低位变高位,高位变低位。我们需要两个变量,一个存操作数i,另一个存反制的数。
唯一的难题如何反转操作数?我们可以每次只取操作数的最低位,然后拼接到新变量的最低位,然后操作数再舍弃最低位,循环这个过程直到操作数为0,即没有最低位。
int operand=0; //存操作数
int reversal=0; //存反转的数
int low=0; //存最低位
for(int i=100;i<1000;i++)
{
operand = i; //存储操作数i
while(operand!=0) //直到operand 为0
{
low = operand%10; //取操作数最低位
reversal = reversal*10 + low; //拼接最低位
operand /= 10; //等价operand =operand /10,舍弃最低位
}
reversal=operand= 0; //清空,为了下一次操作
}
第3步:判断是否为回文数,只需要判断原操作数是否与反转后的数相等即可,成立则输出原操作数。
int operand=0; //存操作数
int reversal=0; //存反转的数
int low=0; //存最低位
for(int i=100;i<1000;i++)
{
operand = i; //存储操作数i
while(operand!=0) //直到operand 为0
{
low = operand%10; //取操作数最低位
reversal = reversal*10 + low; //拼接最低位
operand /= 10; //等价operand =operand /10,舍弃最低位
}
if(i==reversal) //判断是否为回文数
printf("%d\t",i); //\t是制空符
reversal=operand= 0; //清空,为了下一次操作
}
第4步:整体运行。将这个代码逻辑放入主函数中运行,查看结果。
#include <stdio.h>
int main() {
int operand=0; //存操作数
int reversal=0; //存反转的数
int low=0; //存最低位
printf("100~1000之间的回文数有:\n");
for(int i=100;i<1000;i++)
{
operand = i; //存储操作数i
while(operand!=0) //直到operand 为0
{
low = operand%10; //取操作数最低位
reversal = reversal*10 + low; //拼接最低位
operand /= 10; //等价operand =operand /10,舍弃最低位
}
if(i==reversal) //判断是否为回文数
printf("%d\t",i); //\t是制空符
reversal=operand= 0; //清空,为了下一次操作
}
return 0;
}
运行结果:
第四关解法
首先分析题目,如下:
解题步骤:
第1步:让用户输入一个0~15的十进制整数,并使用变量x存储。
int x; //存操作数
printf("请输入一个十进制数(0~15):");
scanf("%d",&x);
printf("\n"); //换行
if(x>=0&&x<=15)
{
}
第2步:"除 2 取余,逆序排列"。在数学上,把十进制整数数转换为二进制数可以通过 “除 2 取余,逆序排列” 的方法,下图就是十进制转二进制的方法:
首先将十进制除2,得商和余数。循环以下过程:再将商除2,得商和余数。直至商为0结束,然后将余数倒序排列就是二进制数。
我们将用C语言来实现这一数学过程,但值得注意的是从头到尾取的余数是从低位到高位,我们需要进行拼接。
int x = -1; //存操作数
int a1,a2,a3,a4; //存二进制从低至高位
int remainder; //存余数
printf("请输入一个十进制数(0~15):");
scanf("%d",&x);
printf("\n"); //换行
if (x>=0&&x<=15)
{
for(int i=1;i<5;i++) //循环4次
{
remainder = x%2; //取余数
x /= 2; //等价x = x/2,除2得商
switch(i){ //判断除的次数
case 1: a1 = remainder; break;
case 2: a2 = remainder; break;
case 3: a3 = remainder; break;
case 4: a4 = remainder; break;
}
}
}
第三步:拼接二进制位。将a4、a3、a2、a1从高位往低位拼接,a4是最高位,a1是最低位。并且将其二进制形式的数输出。
printf("%d",a4*1000+a3*100+a2*10+a1); //输出二进制形式的数
第4步:整体运行。将这个代码逻辑放入主函数中运行,查看结果。
#include <stdio.h>
int main() {
int x = -1; //存操作数
int a1,a2,a3,a4; //存二进制从低至高位
int remainder; //存余数
printf("请输入一个十进制数(0~15):");
scanf("%d",&x);
printf("\n"); //换行
if(x>=0&&x<=15)
{
for(int i=1;i<5;i++) //循环4次
{
remainder = x%2; //取余数
x /= 2; //等价x = x/2,除2得商
switch(i){ //判断除的次数
case 1: a1 = remainder; break;
case 2: a2 = remainder; break;
case 3: a3 = remainder; break;
case 4: a4 = remainder; break;
}
}
}
printf("%d",a4*1000+a3*100+a2*10+a1); //输出二进制形式的数
return 0;
}
运行结果:
第五关解法
解题步骤:
第1步:循环直到20列,因为第0列和第1列的值是已知的,所以从第2列一直求到第20列,可以使用for语句循环实现。
int num1 = 0; //存上上列
int num2 = 1; //存上列
int now; //存当前列
for(int i=2;i<=20;i++)
{
}
现在每次i就是我们的斐波那契数列的列数,从i=2也就是第2列开始,那么第0列的值为0,第1列的值为1。
第2步:运算逻辑:当前列=上上列+上列。我们只需要每次先求出当前列的值,同时要着眼于未来!注意的是下列=上列+当前列,所以要为下一次更新上上列和上列值,直到i等于20的时候。
int num1 = 0; //存上上列
int num2 = 1; //存上列
int now; //存当前列
for(int i=2;i<=20;i++)
{
now = num1 + num2; //当前列=上上列+上列
//为下列作准备,下列=上列+当前列
num1 = num2;
num2 = now;
}
第3步:输出第20列的值,当循环结束后,此时now的值就为斐波那契数列的第20列的值,直接printf输出即可
int num1 = 0; //存上上列
int num2 = 1; //存上列
int now; //存当前列
for(int i=2;i<=20;i++)
{
now = num1 + num2; //当前列=上上列+上列
//为下列作准备,下列=上列+当前列
num1 = num2;
num2 = now;
}
printf("斐波那契数列第20列=%d",now);
第4步:整体运行。将这个代码逻辑放入主函数中运行,查看结果。
#include <stdio.h>
int main() {
int num1 = 0; //存上上列
int num2 = 1; //存上列
int now; //存当前列
for(int i=2;i<=20;i++)
{
now = num1 + num2; //当前列=上上列+上列
//为下列作准备,下列=上列+当前列
num1 = num2;
num2 = now;
}
printf("斐波那契数列第20列=%d",now);
return 0;
}
运行结果:
在该系列中,文章的前部分采用简短的白话文讲解用法,而后部分采用更深入的角度讲解原理。思考是人类的结晶~如果你觉得有用,给我个点赞、收藏+关注哦~持续更新