选择循环结构的习题
1. 三个数找最大值
#include<stdio.h>
int main()
{
int a = 0 , b = 0 , c = 0;
int t = 0;
scanf("%d%d%d",&a,&b,&c);
if(a>=b)
{
t= a;
}
else
{
t= b;
}
if(c>t)
{
t= c;
}
printf("%d\n",t);
return 0;
}
2. 分段函数求值
#include<stdio.h>
int main()
{
int x=0,y=0;
scanf("%d",&x);
if(x<1)
{
y=x;
}
else if(x>=1 && x<10)
{
y = 2*x-1;
}
else
{
y = 3*x-11;
}
printf("%d\n",y);
return 0;
}
3, 成绩评定
#include<stdio.h>
int main()
{
int score = 0;
int temp = 0;
scanf("%d",&score);
temp = score/10 ;
switch(temp)
{
case 10:printf("A\n");break;
case 9:printf("A\n");break;
case 8:printf("B\n");break;
case 7:printf("C\n");break;
case 6:printf("D\n");break;
default:printf("E\n");
}
return 0;
}
4. 数字的处理与判断
题目描述
给出一个不多于5位的整数,要求 1、求出它是几位数 2、分别输出每一位数字 3、按逆序输出各位数字,例如原数为321,应输出123
输入
一个不大于5位的数字
输出
三行 第一行 位数 第二行 用空格分开的每个数字,注意最后一个数字后没有空格 第三行 按逆序输出这个数
样例输入
12345
样例输出
5
1 2 3 4 5
54321
题解:
#include<stdio.h>
int main()
{
int i, n,count=0 ,x[5];
scanf("%d",&n);
for(i=0;i<5;i++)
{
if(n==0) break;
else{
x[i]=n%10;//将最后一个数字放入数组中
n = n/10;//剩下的数字每次进一位
count++;//次数即数字位数增加一位。
}
}
printf("%d\n",count);
for(i = count-1;i>=0;i--)//由于录入进数组的数字是反的,所以要反正输出,才能输出正的数字。
{
if(i==0)
{
printf("%d\n",x[0]);//如果是最后一位数字就输出一个空位
}
else
{
printf("%d ",x[i]);
}
}
for(i = 0;i<count;i++)//输出倒置的数字字符串。
{
printf("%d",x[i]);
}
return 0;
}
5. 最大公约数和最小公倍数
题目描述
输入两个正整数m和n,求其最大公约数和最小公倍数。
输入
两个整数
输出
最大公约数,最小公倍数
样例输入
5 7
样例输出
1 35
题解:
使用辗转相除法
m n z
m n z
5 2 1
2 1 0
#include<stdio.h>
int main(void)
{
int z,x,y,m=0;
scanf("%d%d",&x,&y);
m=x*y;
while(y>0)
{
z=x%y; /*由于%计算的特殊性,不用区分x和y的大小*/
x=y;//辗转相除法
y=z;
}
printf("%d %d\n",x,m/x);/*最小公倍数的计算方法就是(x*y/最大公倍数) */
return 0;
}
6. 字符串分类统计
题目描述
输入一行字符,分别统计出其中英文字母、数字、空格和其他字符的个数。
输入
一行字符
输出
统计值
样例输入
aklsjflj123 sadf918u324 asdf91u32oasdf/.';123
样例输出
23 16 2 4
题解
#include<stdio.h>
int main()
{
int letter=0, blank=0,number=0,other=0;// 定义为字母,数字,空格,和其他符号
char c;
while((c=getchar())!='\n'){ // 此处涉及到getchar()函数的用法问题,我在别的文档里有写到
if(c>='A'&& c<= 'Z' || c>='a' && c<='z' )// 判断是字母
letter++;
else if(c>='0' && c<='9') //判断是数字
number++;
else if(c==' ') // 判断是空格
blank++;
else
other++;
}
printf("%d %d %d %d",letter,blank, number,other);
return 0;
}
7. Sn的公式求和
题目描述
求Sn=a+aa+aaa+…+aa…aaa(有n个a)之值,其中a是一个数字,为2。 例如,n=5时=2+22+222+2222+22222,n由键盘输入。
输入
n
输出
Sn的值
样例输入
5
样例输出
24690
题解:
#include<stdio.h>
int main()
{
int n =1 , x[1000];//定义一个大型数组,这样子可以存储各种数字
int i ;
int num = 0;
scanf("%d",&n);
x[0] =2;
for(i=1;i<n;i++)
{
x[i]=x[i-1]*10+2;//每次循环都产生一个22.....222,并存入数组中
}
for(i=0;i<n;i++)
{
num+=x[i];//把全部数组成员加起来
}
printf("%d\n",num);
return 0;
}
更好的答案:
#include<stdio.h>
int main()
{
int n,Sn = 0,i,a = 0;
scanf("%d",&n);
for(i=0; i<n; i++){//直接合并了两个for循环,这样子速度更快,还不需要使用数组,我还是未能深入认识循环结构。
a = a * 10 + 2;
Sn = Sn + a;
}
printf("%d\n",Sn);
return 0;
}
精简后我的答案:
#include<stdio.h>
int main()
{
int n =1 , x[100],i;
int num = 0;
scanf("%d",&n);
x[0]=2;
for(i=0;i<n;i++)//这里默认了n比100小,所以这样子是不对的,但是数组的大小是不能用变量定义的。
{
x[i+1]=x[i]*10+2;
num+=x[i];
}
printf("%d\n",num);
return 0;
}
8. 阶乘求和
题目描述
求Sn=1!+2!+3!+4!+5!+…+n!之值,其中n是一个数字(n不超过20)。
输入
n
输出
Sn的值
样例输入
5
样例输出
153
题解:
#include<stdio.h>
int main()
{
long double sum=0,sn=1;// 由于数据量很大,最好使用long double 数据类型,这样子可以避免精度问题。
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
sn=sn*i; //这与上面的题目很像。
sum=sum+sn;
}
printf("%.0Lf",sum);
return 0;
}
9.求和训练 (大杂烩)
题目描述
求以下三数的和,保留2位小数 1~a之和 1~b的平方和 1~c的倒数和
输入
a b c
输出
1+2+…+a + 12+22+…+b^2 + 1/1+1/2+…+1/c
样例输入
100 50 10
样例输出
47977.93
题解:
#include<stdio.h>
int main()
{
double a =0, b =0 ,c =0;
double num1 = 0, num2 = 0,num3 =0 ;
int i ;
scanf("%lf %lf %lf",&a,&b,&c);// 注意使用了double最为数据类型就要用“lf”来接收数据
for(i=1;i<=a;i++)
num1 += i;
for(i=1;i<=b;i++)
num2 +=i*i;
for(i=1;i<=c;i++)
num3+=1.0/i //此处只有使用1.0才可以得出一个小数。
printf("%.2lf\n",num1+num2+num3);
return 0;
}
10. 水仙花数
题目描述
打印出所有"水仙花数",所谓"水仙花数"是指一个三位数,其各位数字立方和等于该本身。 例如:153是一个水仙花数,因为153=13+53+3^3。
输入
无
输出
输出每一个水仙花数,一个数占一行
样例输入
无
样例输出
无
题解:
#include<stdio.h>
int main()
{
int number =100;
int a=0 , b=0 , c =0;
for(number =100;number<1000;number++)
{
a= number/100;
b= (number/10)%10;
c= number%10;
if(a*a*a+b*b*b+c*c*c == number)
printf("%d\n",number);
}
return 0;
}
11. 自由下落的距离计算
题目描述
一球从M米高度自由下落,每次落地后返回原高度的一半,再落下。 它在第N次落地时反弹多高?共经过多少米? 保留两位小数
输入
M N
输出
它在第N次落地时反弹多高?共经过多少米? 保留两位小数,空格隔开,放在一行
样例输入
1000 5
样例输出
31.25 2875.00
题解:
#include<stdio.h>
int main()
{
double height = 0,sum = 0;
int n,i;
scanf("%lf %d",&height,&n);
for(i=0;i<n;i++)
{
if(i==0){
sum =sum+height;
height=height/2.0;
}
else{
sum=sum+height*2.0;
height =height/2.0;
}
}
printf("%.2lf %.2lf",height,sum);
return 0;
}
这道题的关键在于算法,走过的路程不算最后的一次弹跳,那么中间的所有弹跳都是需要乘以二的,第一次下落无法乘以二,所以需要一个判断(for 循环)。
还有另一种办法,就是数学建模的思路,通过数学公式来轻松计算。
题解:
一球从M米高度自由下落,每次落地后返回原高度的一半,再落下。
1.第N次下落时反弹所得的高度很容易得到,每次反弹是上一次的1/2,第N次就是第一次的(1/2)^N.
2.接下来分析如何求得第N次落地总共经历的高度。为了得到发现规律,简化算法,我们可以把过程分为两部分来求:
经过的总路程=球下落的总路程+上升的总路程。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ck6BwwME-1612600832752)(C:\Users\huwei\AppData\Roaming\Typora\typora-user-images\image-20210206113547849.png)]
从图片容易发现,每次上升/下降的高度是上次的二分之一,容易看出这是一个等比数列。(不懂等比数列的话,可以百度一下很容易)
根据等比数列求和公式,可知N次落地时:
下路的总路程之和=M(1-0.5N)/0.5=2M(1-0.5N)
上升的总路程之和=M/2(1-0.5(N-1))/0.5=M(1-0.5(N-1))
这里唯一需要注意的就是,上升路程计算公式1-0.5^(N-1),这是因为第一次落地的时候,还没有反弹,上升高度为零。
#include <stdio.h>
#include <math.h>
int main()
{
double M,N;
double up,down;//分别用来计算上升/下降的总路程
scanf("%lf %lf",&M,&N);
up=M*(1-pow(1.0/2.0,N-1)); //计算上升的总路程
down=2*M*(1-pow(1.0/2.0,N)); //计算下降的总路程
printf("%.2lf %.2lf\n",M*pow(1.0/2.0,N),up+down);
//pow是幂次函数
return 0;
}
这里可以发现数学的好处,我们使用了一个公式,把整个代码简化了很多,而且更加的容易理解。
12. 迭代法求平方根
迭代法就是辗转法,就是不断用旧值替代新值从而可以得到目标值的办法
要熟练运用迭代思维。
题目描述
用迭代法求 平方根
公式:求a的平方根的迭代公式为: X[n+1]=(X[n]+a/X[n])/2 要求前后两次求出的差的绝对值少于0.00001。 输出保留3位小数
输入
X
输出
X的平方根
样例输入
4
样例输出
2.000
题解:
#include<stdio.h>
#include<math.h>
int main()
{
double x,x1 =1.0;
double a;
scanf("%lf",&a);
do{
x = x1;
x1 = (x+a/x)/2.0;/*迭代法的思维,关键是搞清楚旧值是哪一个,新值是哪一个,方向一定是旧值传往新值*/
}while(fabs(x-x1)>0.00001);
printf("%.3lf\n",x);
return 0;
}
/* x= (x1+a/x1)/2.0; 此处的x1是旧值,x是新值,但是新值又传向了旧值x1,导致新旧两值相同。
x1= x */
13. 筛选N以内的素数
题目描述
用简单素数筛选法求N以内的素数。
输入
N
输出
2~N的素数
样例输入
100
样例输出
2
3
5
7
11
13
17
19
23
29
31
37
41
43
47
53
59
61
67
71
73
79
83
89
97
题解:
#include<stdio.h>
int main()
{
int n,a;
scanf("%d",&n);
int i,j;
for(i=2;i<=n;i++)
{
a=0;/*目标:一旦检测到又除了自己和1的能够整除的数,就加一个1 ,从而充当了一次计数器的功能*/
for(j=2;j<i;j++)/*此处的j不能和i相等,这样子会一个数字都输出不了*/
if(i%j==0)
a++;
if(a==0)/*又是一个很二进制的想法,非0即1,这样子的做法最符合计算机的思维。*/
printf("%d\n",i);
}
return 0;
}