5级-连斩五关

前情回顾:在4级的时候,我们学习了程序的流程控制


目录

关卡列表

突破关卡

第一关解法

第二关解法

第三关解法

第四关解法

第五关解法


 

关卡列表

你遇到的关卡如下:

第一关:输出100~1000之间的水仙花数

水仙花数是指一个三位数,它的每个数位上的数字的立方和等于它本身。例如,153 是一个水仙花数,因为1^3+5^3+3^3=1+125+27=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;
}    

 运行结果:


         在该系列中,文章的前部分采用简短的白话文讲解用法,而后部分采用更深入的角度讲解原理。思考是人类的结晶~如果你觉得有用,给我个点赞、收藏+关注哦~持续更新 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值