谭浩强c程序设计例题+习题 第五章 选择结构程序设计

第五章 循环结构程序设计

例5.1 求1+2+3+…+100∑n
#include<stdio.h>
int main(){
	int i,n=100,sum=0;
	scanf("%d",&n);
	for(i=0;i<=n;i++){
		sum+=i;
	}
	printf("%d",sum);
}
例5.2 用do while求和
#include<stdio.h>
int main(){
	int i=1,sum=0;
	do{
		sum+=i;
		i++;
	}while(i<=100);
	printf("sum=%d\n",sum);
	return 0;
}
例5.4 在全系1000名学生中举行慈善募捐,当总数达到10万元时就结束,统计此 时捐款的人数以及平均每人捐款的数目。

循环次数不能确定,可以设置最大值1000,在循环体中检查是否总数达到10万

#include<stdio.h>
#define sum 100000 
int main(){
	int i;
	float amount,avg,total;
	for(i=1,total=0;i<=1000;i++){
		scanf("%f",&amount);
		total=total+amount;
		if(total>=sum) break;
	}
	avg=total/i;
	printf("num=%d\navg=%10.2f\n",i,avg);
	return 0;
}
例5.5 要求输出100-200的不能被3整除的数
#include<stdio.h>
int main(){
	int n;
    for(n=100;n<=200;n++){
        if(n%3==0) continue;
        printf("%d ",n);
    }
    printf("\n");
    return 0;
}
例5.6 输出以下4*5的矩阵
#include<stdio.h>
int main(){
	int i,j,n=0;
	for(i=1;i<=4;i++){
		for(j=1;j<=5;j++,n++){
			if(n%5==0) printf("\n");
			printf("%d\t",i*j);
		}
	}
	printf("\n");
	return 0;
}
例5.7 用公式求π的近似值

在这里插入图片描述

#include<stdio.h>
#include<math.h>
int main(){
	int sign=1;
	double pi=0.0,n=1,term=1.0;
	while(fabs(term)>=1e-6){
		pi=pi+term;
		n=n+2;
		sign=-sign;
		term=sign/n;
	}
	pi=pi*4;
	printf("%lf\n",pi);
	return 0;
}
例5.8 求斐波那契数列的前40个数
  • 第一二个数是1,从第三项开始,该数是前面两个数之和

  • 古典数学问题:有一对兔子,从出生后三个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假设所有兔子不死,问每个月的兔子总数

#include<stdio.h>
int main(){
	int f1=1,f2=1,f3;
    int i;
    printf("%12d\n%12d\n",f1,f2);
    for(i=1;i<=38;i++){
        f3=f1+f2;
        printf("%12d\n",f3);
        f1=f2;
        f2=f3;
    }
    return 0;
}
#include<stdio.h>
int main(){
	int f1=1,f2=1;
    int i;
    
    for(i=1;i<=20;i++){
    	printf("%12d\n%12d\n",f1,f2);
        if(i%2==0) printf("\n");;
        f1+=f2;
        f2+=f1;
    }
    return 0;
}
例5.11 翻译密码

为使电文保密,往往按一定规律将其转换成密码,收报人再按约定的规律将其译回原文。例如,可以按以下规律将电文变成密码:将字母A变成字母E,a变成e,即变成其后的第4个字母,W变成A,X变成B,Y变成C,Z变成D,见图5.20。

字母按上述规律转换,非字母字符保持原状不变,如“China !”转换为“GImre !”。从键盘输入一行字符,要求输出其相应的密码。
在这里插入图片描述

#include<stdio.h>
int main(){
    char c;
    c=getchar();
    while(c!='\n'){
        if((c>='a'&&c<='z')||(c>='A'&&c<='Z')){
            if(c>='W'&&c<='Z'||c>='w'&&c<='z')
                c=c-22;
            else c=c+4;
        }
        printf("%c",c);
        c=getchar();
    }
    printf("\n");
    return 0;
}

习题

3.输入两个正整数m和n求其最大公约数和最小公倍数
#include<stdio.h>
#include<math.h>
int gcd(int m,int n);
int main(){
	int m,n;
	scanf("%d,%d",&m,&n);
	int result=gcd(m,n);
	printf("%d\n",result);
	return 0;
}
int gcd(int m,int n){
	int temp;
	while(n!=0){
		temp=m%n;
		m=n;
		n=temp;
	}
	return m;
}
4.输入一行字符,分别统计出其中的英文字母、空格、数字和其他字符的个数
#include<stdio.h>
int main(){
	char c;
	int i,zm=0,sp=0,sz=0,qt=0;
	c=getchar();
	while(c!='\n'){
		//英文字母 
		if((c>=65&&c<=90)||(c>=97&&c<=122)){
			zm++;
		}
		//空格 
		else if(c==32){
			sp++;
		}
		//数字
		else if(c>=48&&c<=57){
			sz++;
		} 
		else{
			qt++;
		}
		c=getchar();
	} 
	printf("字母:%d\n空格:%d\n数字:%d \n其他:%d\n",zm,sp,sz,qt);
	return 0;
}
5.求Sn=a+aa+aaa+…+aaaaa(n个a之和),其中a是一个数字,n表示a的位数,n由键盘输入
#include<stdio.h>
#include<math.h>
int main(){
	int a,n;
	int sum=0,num=0;
	scanf("%d",&a);
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		num=num*10+a;
		sum+=num;
	}
	printf("%d",sum);
	return 0;
}
6.求1!+2!+3!+…+n!之和
#include<stdio.h>
#include<math.h>
int main(){
	int a,n;
	int sum=0,num;
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		num=1;
		for(int j=1;j<=i;j++){
			num*=j;
		}
		sum+=num;
	}
	printf("%d",sum);
	return 0;
}
7.求和

在这里插入图片描述

#include<stdio.h>
#include<math.h>
int main(){
	int i;
	double sum=0;
	for(i=1;i<=100;i++){
		sum+=i;
	}
	for(i=1;i<=50;i++){
		sum+=i*i;
	}
	for(i=1;i<=10;i++){
		sum+=1.0/i;
	}
	printf("%lf",sum);
	return 0;
}
8.输出所有的水仙花数
#include<stdio.h>
#include<math.h>
int main(){
	int n;
	int i,g,s,b;
	for(i=100;i<=999;i++){
		g=i%10;
		s=i/10%10;
		b=i/100%10;
		if(pow(g,3)+pow(s,3)+pow(b,3)==i){
			printf("%d\n",i);
		}
	}
	return 0;
}
9.输出1000之内的所有完数
#include<stdio.h>
int main(){
	int sum;
	int i,j;
	
	for(i=1;i<=1000;i++){
		sum=0;
		
		for(j=1;j<i;j++){
			if(i%j==0){
				sum+=j;
			}
		}
		
		if(sum==i){
			printf("%d\n",i);
		}
	}
	return 0;
}
10.求2/1+3/2+5+3+8/5+…前20项之和
#include<stdio.h>
int main(){
	int i;
	double sum=0.0,fz,fm,temp;
	fm=1.0;
	fz=2.0;
	for(i=1;i<=20;i++){
		sum+=fz/fm;
		temp=fz;
		fz=fz+fm;
		fm=temp;	
	}
	printf("%lf",sum);
	return 0;
}
11.小球反弹问题

一个球从100m的高度自由落下,每次落地后反弹回原高度的一半,然后再落下再反弹。求它在第十次落地时共经过多少米,第十次反弹多高。

#include<stdio.h>
int main(){
	double h=100,s=0;
	int i;
	for(i=1;i<=10;i++){
		s+=h;	//下降的距离 
		h=h/2.0;
		s+=h;	//反弹的距离 
	}
	 // 第十次落地后不再反弹,所以需要减去第十次的反弹高度
	s-=h;
	printf("s=%.2lf,h=%.2lf",s,h);
	return 0;
}
12.猴子吃桃问题

猴子第一天摘下若干个桃子,当即吃了一半,还不过,又多吃了一个。。第二天早上又将剩下的桃子吃掉一半,又多吃了一个。以后每天早上都吃了前一天剩下的一半零一个。到第十天早上想吃啥时,桃子只剩下一个了。求第一天摘了多少个桃子。

#include<stdio.h>
int main(){
	int i,sum=1;
	int day=10;
	for(i=day;i>1;i--){
		sum=2*(sum+1);
	}
	printf("%d",sum);
	return 0;
}

13.迭代法求x=根下a ,要求前后两次求出的x的差的绝对值小于10^-5

在这里插入图片描述

#include <stdio.h>
#include <math.h>

int main() {
    double x1, x2, a;
    
    // 读取用户输入的值
    printf("请输入一个正数: ");
    scanf("%lf", &a);
    
    // 初始近似值
    x1 = a / 2.0;

    // 使用while循环实现迭代法
    while (1) {
        x2 = (x1 + a / x1) / 2.0;
        if (fabs(x1 - x2) < 1e-5) {
            break;
        }
        x1 = x2;
    }
    
    // 打印结果
    printf("近似值: %lf\n", x2);
    
    return 0;
}


14.用牛顿迭代法求下面方程在1.5附近的根

牛顿迭代法的公式是:xn+1=xn−f(xn)/f′(xn)

首先,我们需要定义函数 f(x) 及其导数 f′(x)

对于 f(x)=2x3−4x2+3x−6

其导数 f′(x)是:f′(x)=6x2−8x+3

#include <stdio.h>
#include <math.h>

// 定义函数 f(x)
double f(double x) {
    return 2 * x * x * x - 4 * x * x + 3 * x - 6;
}

// 定义函数 f'(x)
double df(double x) {
    return 6 * x * x - 8 * x + 3;
}

int main() {
    double x0 = 1.5;  // 初始猜测值
    double x1;
    double tolerance = 1e-5;  // 允许误差
    int max_iterations = 100; // 最大迭代次数
    int iteration = 0;

    while (1) {
        x1 = x0 - f(x0) / df(x0);  // 牛顿迭代公式

        // 检查误差是否在允许范围内
        if (fabs(x1 - x0) < tolerance) {
            break;
        }

        // 更新 x0
        x0 = x1;
        iteration++;

        // 检查是否超过最大迭代次数
        if (iteration >= max_iterations) {
            printf("迭代次数超过最大限制,未能找到根。\n");
            return 1;
        }
    }

    printf("在 1.5 附近的根为: %lf\n", x1);
    printf("迭代次数: %d\n", iteration);
    return 0;
}

定义函数 f(x) 和它的导数 df(x)

选择初始猜测值 x0 = 1.5

while 循环中,使用牛顿迭代公式计算新的近似值 x1

检查前后两次迭代结果的差值是否小于允许误差 tolerance。如果是,则跳出循环。

更新 x0x1,继续下一次迭代。

如果迭代次数超过最大限制 max_iterations,则打印错误信息并退出。

打印找到的根和迭代次数

15.二分法求以上方程在(-10,-10)的根

二分法是一种用于求解连续函数在给定区间内的根的数值方法。对于函数 f(x)=0f(x) = 0f(x)=0 ,二分法的基本思想是逐步缩小根所在的区间,直到区间长度足够小。

#include <stdio.h>
#include <math.h>

// 定义方程 f(x) = 2x^3 - 4x^2 + 3x - 6
double f(double x) {
    return 2*x*x*x - 4*x*x + 3*x - 6;
}

int main() {
    double a = -10;  // 区间的左端点
    double b = 10;   // 区间的右端点
    double c;        // 区间的中点
    double tolerance = 1e-6; // 精度要求
    int max_iter = 1000; // 最大迭代次数
    int iter = 0; // 当前迭代次数

    if (f(a) * f(b) >= 0) {
        printf("The function does not have opposite signs at the endpoints.\n");
        return -1;
    }

    while ((b - a) / 2 > tolerance && iter < max_iter) {
        c = (a + b) / 2;  // 计算中点
        if (f(c) == 0) {
            break;  // 找到精确根
        } else if (f(a) * f(c) < 0) {
            b = c;  // 根在 [a, c] 区间内
        } else {
            a = c;  // 根在 [c, b] 区间内
        }
        iter++;
    }

    printf("Root: %.6f\n", c);
    printf("Iterations: %d\n", iter);

    return 0;
}

16.输出以下图形

​ s

sss

sssss

sssssss

sssss

sss

​ s

#include <stdio.h>

int main() {
    int i, j;
    int n = 7;  // 最高行数

    // 打印上半部分
    for (i = 1; i <= n; i += 2) {
        for (j = (n - i) / 2; j > 0; j--) {
            printf(" ");  // 打印空格
        }
        for (j = 0; j < i; j++) {
            printf("s");  // 打印字符 's'
        }
        printf("\n");
    }

    // 打印下半部分
    for (i = n - 2; i > 0; i -= 2) {
        for (j = (n - i) / 2; j > 0; j--) {
            printf(" ");  // 打印空格
        }
        for (j = 0; j < i; j++) {
            printf("s");  // 打印字符 's'
        }
        printf("\n");
    }

    return 0;
}

17.乒乓球比赛找选手名单

两个乒乓球队进行比赛,各出3人。甲队为A,B,C 3人,乙队为X,Y,Z 3人。已抽签决定比赛名单。有人向队员打听比赛的名单,A说他不和X比,C说他不和X,Z比,请编程序找出3对赛手的名单。

#include <stdio.h>

int main() {
    int A_battle, B_battle, C_battle;

    // 穷举所有可能的配对
    for (A_battle = 'X'; A_battle <= 'Z'; A_battle++) {
        for (B_battle = 'X'; B_battle <= 'Z'; B_battle++) {
            for (C_battle = 'X'; C_battle <= 'Z'; C_battle++) {
                // 检查配对是否符合条件
                if (A_battle == 'X' || C_battle == 'X' || C_battle == 'Z' ||
                    B_battle == A_battle || B_battle == C_battle || A_battle == C_battle) {
                    continue;
                }

                // 输出有效的配对
                printf("A vs %c\n", A_battle);
                printf("B vs %c\n", B_battle);
                printf("C vs %c\n", C_battle);
                printf("\n");
            }
        }
    }

    return 0;
}

  • 16
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值