循环结构程序设计典型例题例1:有数列2/3、4/5、6/9、10/15……求此数列前30项的和。
算法分析:对于数列的题,首先要找出通项公式,或前后项的计算关系公式,根据公式求所需。
由于数列的题一般执行次数能确定,用for语句来编写比较方便。
此题,前后项的关系是:后一项的分子是前一项的分母加1,后一项的分母是前一项的分子加分母。
解题思路是用循环语句求各项,并把值累加,因为是求前30项的和,循环执行30次。
1. 初值i=2,j=3,s=0;2. 用n从1到30循环3. s=s+ i/j;4. c=i; i=j+1; j=c+j;5.输出s;程序:#include<>main( ){ int i=2,j=3,n,c;float s=0;for(n=1;n<=30;n++){ s=s+(float)i/j;c=i;i=j+1;j=c+j;}printf(“\n%f”,s);}此题中的n与循环体中的执行语句没有数值上的联系,仅仅用做决定循环执行的次数。
例2:下面这个程序,想想它实现的是什么功能?#include<>main( ){ int i,s=0;for(i=1;i<=100;i++){if(i%5==0) continue;s=s+i;}printf(“\n%d”,s);}在左边的程序中,i从1到100循环,当i是5的倍数时,直接进入下一个i,当i不是5的倍数时,把i累加到s,最后输出s。
所以,这个程序实现的是求1~100中间所有非5的倍数的数之和。
例3:输出n~m中(0<n<m)能被3整除,且至少有一个数字是5的所有数。
算法分析:1 输入n与m的值2 用整型变量a从n-m循环,每次值加13.若a能被3整除,执行第4步,否则执行第9步4令整型变量x=a5.若x>0,执行第6步,否则执行第9步=x%107.若i值不为5,执行第8步,否则输出a,并执行第9步=x/10,并返回第5步9.返回第2步,察看下一个a程序:#include<>main( ){ long a,x,i,t,n,m;scanf(“%ld%ld”,&n,&m);for(a=n;a<=m;a++)if(a%3==0){ x=a;while(x>0){ i=x%10;if(i==5) {printf(“\t%ld”,a);break;} x=x/10;}}}问:能把a%3==0也放到for循环语句的表式2中,写成a<=m&&a%3==0吗?答:不可以!例4:求3-150中所有素数的和。
算法分析:1.用变量a从3到150循环,每次值增加12.用变量i从2到a-1循环,每次值增加13.若a%i==0 ,结束i的循环,执行第4步4.若i==a,把a累加到s上。
5.输出s的值注意:此题中执行第4步时有两种情况。
第一种:在第3步中发现了满足a%i==0的情况,直接跳出了i的循环,此时的i一定是在2到a-1中间的一个值,而且a不是素数。
第二种:一直没有发现满足a%i==0的i,在i==a时,不再满足i循环的执行条件,i循环结束,此时的a是素数!程序:#include<>main( ){ int a,s=0,i;for(a=3;a<=150;a++){ for(i=2;i<=a-1;i++)if(a%i==0) break;if(a==i) s=s+a;}printf(“\n%d”,s)}求素数的方法很多,大同小异。
此题可以做一些改动。
如:i的值可以是从2取到sqrt(a);可以不用最后察看i的值,而是通过在发现因子时改动标志变量,最后根据标志变量的值判断是否是素数。
例5:有一个八层高的灯塔,每层所点灯数都等于上一层的两倍,一共有765盏灯,求塔底灯数。
算法分析:此题的关键在于塔顶的灯数,只要知道了塔顶的灯数,就可知道塔底灯数。
这里采取试探的方法来求塔顶灯数。
设塔顶灯数为x,x的初值从1开始循环,每次值加1。
求出相应的灯的总数,总数不为765,继续下一个x的循环,直到某次求得灯总数为765时,结束x的循环,输出此时塔底灯数。
从1开始循环,每次值加 12.设k初值x,计算每层灯数。
设s初值0,累加每层灯数3. i从1到8循环,每次值加14. s=s+ k; k=k*2;5.如果s==765 ,结束x的循环4. s=s+ k; k=k*2;程序:#include<>main( ){ int x,s,i,k;for(x=1;;x++){ s=0;k=x;for(i=1;i<=8;i++){s=s+k;k=k*2;}if(s==765) break;}printf(“\n%d”,k/2);}例5:已知a>b>c>0,a、b、c为整数,且a+b+c<100,求满足1/a2+1/b2=1/c2的a、b、c 共有多少组?算法分析:这是一道典型的三重嵌套循环的题目。
a、b、c都是位于1到99之间整数。
编程的基本思路是:找出1到99之间的所有a、b、c的排列,察看同时满足a>b>c、a+b+c<100、1/a2+1/b2=1/c2这三个条件的a、b、c有多少组。
值得注意的是, 1/a2+1/b2=1/c2这个条件并不能简单的原样照写,因为在求分数的过程中必然有四舍五入,不能得出真正的准确的结果,必须把条件变形成:c2(a2+b2)=a2b2才能得出正确的结果。
从1到99循环从1到99循环从1到99循环4.若a>b&&b>c&&a+b+c<100&&c*c*(a*a+b*b)==a*a*b*b,统计找到了一组5.输出找到的组数程序:#include<>main( ){ long a,b,c,n=0;for(c=1;c<=97;c++)for(b=c+1;b<=98;b++)for(a=b+1;a<=99;a++)if(a+b+c<100&&c*c*(a*a+b*b)==a*a*b*b)n++;pr intf(“\n%ld”,n);}特别注意此题中变量不能定义成int型。
此题可做改进,在循环时确保a>b>c,而不需要再在if中判断。
改进如下所示:for(a=1;a<=99;a++)for(b=1;b<=99;b++)for(c=1;c<=99;c++)if(a>b&&b>c&&a+b+c<100&&c*c* (a*a+b*b)==a*a*b*b)n++;例6:e=1+1/1!+1/2!+….+1/n!(精度为1e-6)分析:用变量e求和,e初值为1。
用变量t求阶乘,t初值为1。
用变量i从1开始累加循环,t=t*i,e=e+t。
#include<>void main( ){ int i=1;long t=1;float e=1;while(e-(int)e>=1e-6){ t=t*i;e=e+t;i++;}printf(“\n%.10f”,e);}例7:数列1,1,2,3,5,8…..有f(n)=f(n-1)+f(n-2),f(1)=1,f(2)=1,求f(40)。
分析:用变量f1、f2、f作为数列相邻的三项,初值f1=1,f2=1。
用变量n从3到40循环,f=f1+f2,f1=f2,f2=f.#include<>main( ){ long f1=1,f2=1,f,n;for( n=3;n<=40;n++){ f=f1+f2;f1=f2;f2=f;}printf(“\nf=%ld”,f);}思考:求14万之内的最大的f(n).例8: Sn=1-1/3+1/5-1/7+…1/(2n-1) 求s(100)(保留4位小数)分析:用变量s求和,s初值为0。
用变量n从1到100循环,如果n是奇数(n%2!=0),s=s+1/(2*n-1),否则s=s-1/(2*n-1) 。
#include<>main( ){int n;float s=0;for( n=1;n<=100;n++)if(n%2!=0) s=s+(2*n-1)else s=(2*n-1);printf(“\n%.4f”,s);}例9:用牛顿迭代法求方程f(x)=2x3-4x2+3x-7=0在x=附近的实根,直到满足|xn-xn-1|<10-6为止。
牛顿迭代公式为:xn=xn-1-f(xn-1)/f ’(xn-1)算法分析:牛顿迭代法认为,以任意一个x的初值开始,都可以根据牛顿迭代公式xn=xn-1-f(xn-1)/f(xn-1)求出一串x的序列,这个序列将越来越趋向于某一个值,这个值就是方程f(x)的一个实根。
#include<>#include<>main( ){ float x=2. 5,x0,f,f2;do{ x0=x;f=2*x0*x0*x0-4*x0*x0+3*x0-7;f2=6*x0*x0-8*x0+3;x=x0-f/f2;}while(fabs(x-x0)>=10e-6);printf(“%f”,x);}例10:求1000以内最大的20个素数之和。
分析:用变量s求和,s初值为0。
用变量I统计以求得素数的个数,I初值为0。
用变量a 从1000到1循环,如果a是素数,则s=s+a,I++。
当i值等于20时,跳出循环。
main( ){int a,s=0,I=0, j;for( a=1000;a>=1;a--){for( j=2;j<a;j++)if(a%j==0) break;if( j==a){ s=s+a; I++; }if(I==20) break;}printf(“\n%d”,s);}例11:[200,1000]的双胞胎数的对数。
双胞胎数:两素数差为2称为双胞胎数。
分析:用变量n统计以求得双胞胎数的对数,n初值为0。
用变量a从200到998循环,如果a是素数,则令变量b=a+2,如果b也是素数,则n值增1。
素数求法同前,用变量I 循环。
main( ){int a,b,n=0,I;for(a=200;a<=998;a++){for(I=2;I<a;I++)if(a%I==0) break;if(a==I ){b=a+2;for(I=2;I<b;I++)if(b%I==0) break;if(b==I ) n++;}}printf(“\n%d”,n);}例12:求[10,200]间可以被其因子的个数整除的整数的个数。