第五章 循环结构程序设计
本章重点:公约数公倍数,水仙花,各类循环级数求和,求方程根
目录
5.2 求π得近似值,并输出循环次数
#include <stdio.h>
#include<math.h>
int cal(double limit);
int main()
{
double i,item,flag=1,sum=0,limit=1e-6;
int count=0;
for(i=1;fabs(flag/(2*i-1))>=limit;i++)
{
item=flag/(2*i-1);
sum=sum+item;
flag=-flag;
count++;
}
printf("while sign <= %.10f: \nπ = %.8f \ncount = %d\n",limit,sum*4,count);
count=cal(1e-8);
printf("count = %d",count);
return 0;
}
int cal(double limit)//传入fabs(t)的最小项限制,抽象成一个函数,返回循环次数,并打印π的近似值
{
double i,item,flag=1,sum=0;
int count=0;
for(i=1;fabs(flag/(2*i-1))>=limit;i++)
{
item=flag/(2*i-1);
sum=sum+item;
flag=-flag;
count++;
}
printf("while sign <= %.10f: \nπ = %.8f\n",limit,sum*4);
return count;
}
/*
输出结果
while sign <= 0.0000010000:
π = 3.14159065
count = 500000
while sign <= 0.0000000100:
π = 3.14159263
count = 50000000
*/
5.3最大公约数 最小公倍数
#include <stdio.h>
int gys( int n,int m);
int gbs( int n,int m);
int main()
{
int n,m,temp,gys,gbs;
printf("intput: \n");
scanf("%d %d",&n,&m);
gbs=m*n;
if(n<m)
{
temp=n;
n=m;
m=temp;
}
printf("n m\n");
printf("%d %d\n",n,m);
while(m)
{
temp=n%m;
n=m;
m=temp;
printf("%d %d\n",n,m);
}
printf("gys = %d , gbs = %d\n",n,gbs/n);
return 0;
}
/* 你的代码将被嵌在这里 */ //抽象为函数形式
int gys( int n,int m)
{
int temp;
if(n<m)
{
temp=n;
n=m;
m=temp;
}
while(m)
{
temp=n%m;
n=m;
m=temp;
}
return n;
}
int gbs( int n,int m)
{
return n*m/gys(n,m);
}
/*
输出结果
intput:
35 49
n m
49 35
35 14
14 7
7 0
gys = 7 , gbs = 245
*/
5.4 统计一行字符中的英文字母,空格,数字和其他字符
#include <stdio.h>
int statistics(char c);
int main()
{
char c;
int sta[4]={0};
while((c=getchar())!='\n')
{
sta[statistics(c)]++;
}
printf("英文字母: %d , 空格: %d , 数字: %d , 其他字符: %d",sta[0],sta[1],sta[2],sta[3]);
return 0;
}
int statistics(char c) //抽象为函数形式
{
if((c>='A'&&c<='Z')||(c>='a'&&c<='z'))
return 0;
else if(c==' ')
return 1;
else if(c>='0'&&c<='9')
return 2;
else
return 3;
}
/*
输出结果
I am a student.
英文字母: 11 , 空格: 3 , 数字: 0 , 其他字符: 1
*/
5.5 Sn=a+aa+aaa+……+aa……a{注:n个a}
#include <stdio.h>
int fact(int a,int n);
int main()
{
int n,a;
scanf("a=%d n=%d",&a,&n);
int sum;
sum=fact(a,n);
printf("sum = %d",sum);
return 0;
}
int fact(int a,int n)
{
int i,j,item=0,sum=0;
for(i=1;i<=n;i++)
{
for(item=0,j=1;j<=i;j++)
{
item=item*10+a;
}
sum+=item;
}
return sum;
}
/*
输出结果
a=2 n=5
sum = 24690
*/
5.6 求阶乘之和
#include <stdio.h>
double fact(int n);
int main()
{
int n;
scanf("%d",&n);
double sum;
sum=fact(n);
printf("sum = %0.f",sum);
return 0;
}
/*这里采用double的原因主要是int的范围受限,double的范围更大,才能打印出20! */
double fact(int n)
{
double i,j,item=1,sum=0;
for(i=1;i<=n;i++)
{
item=item*i;
sum+=item;
}
return sum;
}
5.7 复合求和
#include <stdio.h>
double addsum(int k);
double addsquare(int k);
double adddivide(int k);
int main()
{
int k,n,m;
scanf("%d %d %d",&k,&n,&m);
double sum;
sum=addsum(k)+addsquare(n)+adddivide(m);
printf("sum = %f",sum);
return 0;
}
/* 你的代码将被嵌在这里 */
double addsum(int k)
{
double i,sum=0;
for(i=1;i<=k;i++)
sum+=i;
return sum;
}
double addsquare(int k)
{
double i,sum=0;
for(i=1;i<=k;i++)
sum+=(i*i);
return sum;
}
double adddivide(int k)
{
double i,sum=0;
for(i=1;i<=k;i++)
sum+=(1/i);
return sum;
}
/*输出结果
100 50 10
sum = 47977.928968
*/
5.8 求水仙花数
#include <stdio.h>
#include<math.h>
int isnarcissistic(int n);
int main()
{
int i,n;
scanf("%d",&n);
if(isnarcissistic(n))
printf("yes,%d is narcissistic\n\n",n);
else
printf("No,%d is not narcissistic\n\n",n);
printf("output between 100~%d total narcissistic:\n\n",n);
for(i=100;i<=n;i++)
if(isnarcissistic(i))
printf("%d is narcissistic\n",i);
return 0;
}
/* 你的代码将被嵌在这里 */
int isnarcissistic(int n) //判定一个数是不是水仙花数;
{
//第一步确定该数是几位数。小于3位的必不是水仙花数。
int i=n,j,digit=1;
while(i/=10) digit++;
if(digit<3) return 0;
//第二步根据公式求出sum
int sum=0,item;
for(i=n;i>0;i/=10)
{
item=i%10;
/*不用math.h
int sitem=1;
item=i%10;
for(sitem=1,j=digit;j>0;j--)
sitem=sitem*item;
sum=sum+sitem;
*/
sum=sum+pow(item,digit);
}
//第三部判定水仙花
if(sum==n)
return 1;
else
return 0;
}
5.9 求完数
#include <stdio.h>
int isPerfectnumber(int n);
int main()
{
int i,n;
scanf("%d",&n);
if(isPerfectnumber(n))
printf("yes,%d is Perfect number\n\n",n);
else
printf("No,%d is not Perfect number\n\n",n);
printf("output between 1~%d total Perfect number:\n\n",n);
for(i=2;i<=n;i++)
if(isPerfectnumber(i))
printf("%d is Perfect number\n",i);
return 0;
}
/* 你的代码将被嵌在这里 */
int isPerfectnumber(int n) //判定一个数是不是完数;
{
//因子和
int i,sum=0;
for(i=1;i<n;i++) ///遍历1-除本身外的所有数
{
if(n%i==0) //找出因子
sum+=i; //因子求和
}
if(sum==n) //判定完数
return 1;
else
return 0;
}
/*
输出结果
1000
No,1000 is not Perfect number
output between 1~1000 total Perfect number:
6 is Perfect number
28 is Perfect number
496 is Perfect number
*/
5.10 求分数序列
#include <stdio.h>
int main()
{
//分子=前一项分子分母之和 up=up+down
//分母=前一项分子 down=up
int i,sign,up=2,down=1,temp;
double sum;
scanf("%d",&sign);
sum=1.0*up/down;
for(i=2;i<=sign;i++)
{
temp=up; //保留前一项分母
up=up+down; //求新项的分母
down=temp; //求新项的分子,从保留的哪里取。
sum=sum+1.0*up/down; //求和
}
printf("前 %d 项之和为 = %f",sign,sum);
return 0;
}
5.11 求自由落体路程和反弹高度(做图很重要)
第几次落地 | 第一次落地经过位移 x | 第一次反弹的高度 rh |
---|---|---|
1 | 100 | 50(100/2) |
2 | 100+50+50=200(弹起来也有高度别忘记了) | 25(50/2) |
3 | 200+25+25=250 | 12.5(25/2) |
……(找规律) | …… | …… |
n(n>=2) | 100+2*前一项反弹高度 xn=xn-1+2*rhn-1 | 100/(2n) |
#include <stdio.h>
int main()
{
int i,count;
double heigh,displace=0,rebound_h=0;
scanf("%lf %d",&heigh,&count);
//0次的时候直接输出0 0;
if(count==0)
printf("displace = %.1f rebound_h = %.1f",displace,rebound_h);
else
{
//第一次落地情况比较特殊直接在循环外赋值
displace=heigh;
rebound_h=heigh/2;
//当落地次数>=2时呈现出规律
for(i=2;i<=count;i++)
{
displace=displace+2*rebound_h;
rebound_h=rebound_h/2;
}
printf("displace = %.1f rebound_h = %.1f",displace,rebound_h);
}
return 0;
}
/*
输出结果
count=0
100 0
displace = 0.0 rebound_h = 0.0
----------------------------
count=1
100 1
displace = 100.0 rebound_h = 50.0
----------------------------
count=10
100 10
displace = 299.6 rebound_h = 0.1
*/
5.12 猴子吃桃
#include <stdio.h>
int main()
{
int i,day,total=1;
printf("第几天剩余1个桃子:");
scanf("%d",&day);
for(i=day;i>1;i--)
{
total=2*(total+1);
}
printf("The one day peach total = %d",total);
return 0;
}
/*
输出结果
第几天剩余1个桃子:10
The one day peach total = 1534
*/
5.13 迭代法求平方根
//前后两次的差值局对峙小于0.00005
#include<stdio.h>
#include<math.h>
//fabs(x-temp)>=1e-5 中 x-temp 为 float 时需要更小精读的话就会出现错误,如0.0000001,只能去到前6位
int main()
{
int a,n;
double x,temp=0;
scanf("%d",&a);
x=a/2.0;
while(fabs(x-temp)>=1e-5)
{
temp=x; //保存前一项x;
x=1.0*(x+a/x)/2; //计算后一项x;
}
printf("sqrt(%d) = %f",a,x);
return 0;
}
5.14 牛顿迭代法求方程根在某个值附近的根
#include<stdio.h>
#include<math.h>
int main()
{
double value,x,x0,fx,fx2;
scanf("%lf",&value);
x0=value;
fx=2*x0*x0*x0-4*x0*x0+3*x0-6;
fx2=6*x0*x0-8*x0+3;
x=x0-fx/fx2;
while(fabs(x-x0)>=1e-5)
{
x0=x;
fx=2*x0*x0*x0-4*x0*x0+3*x0-6;
fx2=6*x0*x0-8*x0+3;
x=x0-fx/fx2;
}
printf("x = %f",x);
return 0;
}
5.15 二分法求某区间内方程的根
#include<stdio.h>
#include<math.h>
int main()
{
double x0,x1,x2,fx0,fx1,fx2;
do{
printf("enter x1 & x2:");
scanf("%lf %lf",&x1,&x2);
fx1=x1*((2*x1-4)*x1+3)-6;
fx2=x2*((2*x2-4)*x2+3)-6;
}while(fx1*fx2>0);
do{
x0=(x1+x2)/2;
fx0=x0*((2*x0-4)*x0+3)-6;
if((fx0*fx1)<0)
{
x2=x0;
fx2=fx0;
}
else
{
x1=x0;
fx1=fx0;
}
}while(fabs(fx0)>=1e-5);
printf("x=%6.2f\n",x0);
return 0;
}
/*
输出结果
enter x1 & x2:-10 10
x= 2.00
*/
5.16 打印菱形图案
#include<stdio.h>
int main()
{
int n,i,j;
//scanf("%d",&n);
n=4;
for(j=0;j<n;j++)
{
for(i=0;i<n-1-j;i++)
printf(" ");
for(i=0;i<2*j+1;i++)
printf("* ");
printf("\n");
}
n=n-1;
for(j=0;j<n;j++)
{
for(i=0;i<=j;i++)
printf(" ");
for(i=0;i<2*(n-j)-1;i++)
printf("* ");
printf("\n");
}
return 0;
}
/*
输出结果
*
* * *
* * * * *
* * * * * * *
* * * * *
* * *
*
*/
5.17 乒乓球对手名单
分析
做表分析很快能得到结果
X | Y | Z | |
---|---|---|---|
A | 否 | 否 | 是 |
B | 否 | 否 | 是 |
C | 否 | 是 | 否 |
#include<stdio.h>
int main()
{
char i,j,k;
for(i='X';i<='Z';i++)
for(j='X';j<='Z';j++)
for(k='X';k<='Z';k++)
if(i!=j&&i!=k&&j!=k) //不能和自己比赛
{
if(i!='X'&&k!='X'&&k!='Z') //题目条件
printf("三队选手的比赛名单为:\n A--%c B--%c C--%c\n",i,j,k);
}
}