C语言初步(第4周)

本周是习题时间

1.凑硬币:输入一个10元以内的面额,输出所有用一角,两角和五角能组合出的结果

版本一:以角为单位,从低到高进行循环嵌套

#include<stdio.h>
int main()
{
	int x;
	printf("请输入一个十元以下的面额(以角为单位):");
	scanf_s("%d", &x);
	int one=0, two=0, five=0;
	for (one = 1; one <x; one++) {
		if (one + two * 2 + five * 5 == x) {
			printf("%d个一角,%d个两角,%d个五角\n", one, two, five);
		}
		for (two = 1; two < x / 2; two++) {
			if (one + two * 2 + five * 5 == x) {
				printf("%d个一角,%d个两角,%d个五角\n", one, two, five);
			}
			for (five = 1; five < x / 5; five++) {
				if (one + two * 2 + five * 5 == x) {
					printf("%d个一角,%d个两角,%d个五角\n", one, two, five);
				}
			}
		}
	}
	return 0;
}

很明显,前面两个If都不能起作用,因为即便可能没有进入后两个循环,two和five 依旧会被重新赋值为1。而且这样做得到的结果只能是部分的。

版本二:以元为单位,从低到高

#include<stdio.h>
int main()
{
	double x;
	printf("请输入一个十元以下的面额(以元为单位):");
	scanf_s("%lf", &x);
	int one , two , five ;
	for (one = 1; one < x * 10; one++) {
		for (two = 1; two < x * 10 / 2; two++) {
			for (five = 1; five < x * 10 / 5; five++) {
				if (one + two * 2 + five * 5 == x * 10) {
					printf("%d个一角,%d个两角,%d个五角\n", one, two, five);
				}
			}
		}
	}
	return 0;

和版本一相似,只是少了多余的两个if语句且使用了浮点型

版本三:从低到高,多for多If

#include<stdio.h>
int main()
{
	int x;
	int one, two, five;
	int isprime = 1, a = 1,b=1,c=1;
	printf("请输入一个10元一下的面额(以角为单位):");
	scanf_s("%d", &x);
	for (one = 1; one <= x; one++) {
		if (one == x) {
			printf("%d个一角\n",one);
		}
		for (two = 1; two <= x / 2; two++) {
			if (one + two * 2 == x) {
				printf("%d个一角,%d个两角\n", one, two);
			}
			if (two * 2 == x) {
				if (isprime==1) {
					printf("%d个两角\n", two);
					isprime = 0;
				}
			}
			for (five = 1; five <= x / 5; five++) {
				if (five * 5 + two * 2 + one == x) {
					printf("%d个一角,%d个两角,%d个五角\n", one, two, five);
				}
				if (five * 5 == x) {
					if (a==1) {
						printf("%d个五角\n", five);
						a = 0;
					}
				}
				if (five * 5 + two * 2 == x) {
					if (b == 1) {
						printf("%d个两角,%d个五角\n", two, five);
						b = 0;
					}
				}
				if (five * 5 + one == x) {
					if (c == 1) {
						printf("%d个一角,%d个五角\n", one, five);
						c = 0;
					}
				}
			}
		}
	}
	return 0;
}

解决了前两段代码只能输出部分组合的弊端,但是它实在是太冗长了!

版本四:从高到低,最简洁有效!

#include<stdio.h>
int main()
{
	double x;
	printf("请输入一个十元以下的面额(以元为单位):");
	scanf_s("%lf", &x);
	int one, two, five;
	for (five = 0;five <= x* 10/5; five++) {
		for (two = 0; two <= x *10/2; two++) {
			for (one= 0; one <= x*10 ; one++) {
				if (one + two * 2 + five * 5 == x*10) {
					printf("%d个一角,%d个两角,%d个五角\n", one, two, five);
				}
			}
		}
	}
	return 0;
}

换了一种思路,即由低到高对循环进行排序。关键在于它把初始值全部换成了0,这样保证了直接进入里面循环的可能,从而让每种组合从以全部为一角的情况为伊始,逐渐增加两角和五角的组合。达到事半功倍的效果。

版本五:接力break

int main()
{
	int x;
	printf("请输入一个十元以下的面额(以元为单位):");
	scanf_s("%d", &x);
	int one, two, five;
	int exit = 0;
	for (one = 1; one < x * 10; one++) {
		for (two = 1; two < x * 10 / 2; two++) {
			for (five = 1; five < x * 10 / 5; five++) {
				if (one + two * 2 + five * 5 == x * 10) {
					printf("%d个一角,%d个两角,%d个五角\n", one, two, five);
					exit = 1;
				}
			}
			if (exit == 1) break;
		}
		if (exit)break;
	}
	return 0;
}

这是以版本二为基础进行的改造,目的是使得到一组解以后就能够脱离循环。

版本六:goto——

用一种新的表现形式去替代接力break的形式:

#include<stdio.h>
int main()
{
	int x;
	printf("请输入一个十元以下的面额(以元为单位):");
	scanf_s("%d", &x);
	int one, two, five;
	for (one = 1; one < x * 10; one++) {
		for (two = 1; two < x * 10 / 2; two++) {
			for (five = 1; five < x * 10 / 5; five++) {
				if (one + two * 2 + five * 5 == x * 10) {
					printf("%d个一角,%d个两角,%d个五角\n", one, two, five);
					goto out;
				}
			}
		}
	}
	out:
	return 0;
}

2.整数的正序输出

版本一:超复杂

#include<stdio.h>
int main()
{
	int x, a = 0, b = 0;
	int count = 0, m = 0,n = 0, i = 0, mask = 1, isprime = 1;
	printf("请输入一个正整数:");
	scanf_s("%d", &x);
	int t = x, y = x;
	while (t > 0) {
		count++;
		if (t > 9) {
			mask *= 10;
		}
		t /= 10;
	}
	for (; mask > 0; mask /= 10) {
		count--;
		if (x % mask == 0) {
			isprime = 0;
			break;
		}
	}
	while (y > 0) {
		a = y % 10;
		m = m * 10 + a;
		y /= 10;
	}//倒序重排得到新的数
	if(isprime == 1) {
		while (m > 0) {
			b = m % 10;
			printf("%d ", b);
			m /= 10;
		}//得到末尾无0的情况
	}
	if(isprime==0) {
		while (m > 0) {
			b = m % 10;
			printf("%d ", b);
			m /= 10;
		}
		for (; count > 0;count--) {
			printf("0 ");
		}//得到末尾有0的情况
	}
	return 0;
}

版本二:简洁

#include<stdio.h>
int main()
{
	int x;
	scanf_s("%d", &x);
	int mask = 1;
	int t = x;
	while (t > 9) {
		t /= 10;
		mask *= 10;
	}
	do {
		int d = x / mask;
		printf("%d", d);
		if (mask > 9) {
			printf(" ");
		}
		x %= mask;
		mask /= 10;
	} while (mask > 0);
	return 0;
}

3.求最大公约数

版本一:

int main()
{
	int a, b;
	int c = 0;
	printf("请输入两个正整数或零,求它们的最大公约数:");
	scanf_s("%d %d", &a, &b);
	for(int i=1;i<=a;i++){
		if (a% i == 0) {
			if (b % i == 0) {
				c = i;
			}
		}
	}printf("最大公约数为:%d", c);
	return 0;

版本二:辗转相除法

#include<stdio.h>
int main()
{
	int a, b,c=1;
	printf("请输入两个自然数:");
	scanf_s("%d %d", &a, &b);
	if (a == 0) {
		printf("最大公约数为:%d", b);
	}
	else if (b == 0) {
		printf("最大公约数为:%d", a);
	}
	else {
		while (a % b != 0) {
			c = a % b;
			a = b;
			b = c;
		}
		printf("最大公约数为:%d", c);
	}
	return 0;
}

5.数列求和

其一:

#include<stdio.h>
int main()
{
	int n;
	double sum = 0;
	printf("请输入一个正整数:");
	scanf_s("%d", &n);
	for (int i = 1; i <= n; i++) {
		sum += 1.0 / i;
	}
	printf("f(n)=%f", sum);
	return 0;
}

其二:

#include<stdio.h>
int main()
{
	printf("%d\n", 1 % 2);//结果为1
	printf("%f\n", 1 % 2);//结果为0
	printf("%f\n", 1 / 2);//结果为0
	printf("%d\n", 1.0 / 2);//结果为0
	printf("%f\n", 1.0 / 2);//结果为0.5
	int n;
	double sum = 0,sign=1;
	printf("请输入一个正整数:");
	scanf_s("%d", &n);
	for (int i = 1; i <= n; i++) {
		//if (n % 2 == 0) 
			//sum -= 1.0 / i;
		sum +=sign / i;
		sign = -sign;
		//else
			//sum += 1.0 / i;
	}
	printf("f(n)=%f", sum);
	return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值