3.3算法的基本工具和优化技巧----优化算法的基本技巧


1.算数运算的妙用

例题1(统计成绩优秀人数)

一次考试,共考了5门课,统计50个学生中至少有三门成绩高于90分的人数

未优化

#include<stdio.h>

void statistics() {
	int a[5], i, j, s, num = 0;
	for (i = 1; i <= 50; i++) {
		s = 0;
		for (j = 0; j < 5; j++) {
			scanf("%d", &a[i]);
			if (a[i] >= 90) {
				s++;
			}
		}
		if (s >= 3) {
			num++;
		}
	}
	printf("成绩高于90的有%d人", num);
}

void main() {
	statistics();
}

优化

避免了复杂的逻辑表达式,避免了条件判断
s = 0;
		for (j = 0; j < 5; j++) {
			scanf("%d", &a[i]);
			s = s + (a[j] >= 90);
		}

例题2(开灯问题)

例题3(数字圆圈求max min)

图中所示的圆圈中,把相隔一个数据的两个数,称作“一对数”, 编写算法求出乘积最大的一对数和
乘积最小的一对数
求余运算mod的作用,起到循环的作用
#include<stdio.h>

void maxmin() {
	int max = 1, min = 32767, a[100], num, i, k;
	int m, n, s, t;//两组下标
	int p, q;

	printf("input a number:");
	scanf("%d", &num);
	for (i = 0; i < num; i++) {
		scanf("%d", a[i]);
	}
	for (i = 0; i < num; i++) {
		p = (num + i - 1) % num;
		q = (num + i + 1) % num;
		k = a[p] * a[q];
		if (k > max) {
			max = k;
			m = a[p];
			n = a[q];
		}
		if (k < min) {
			min = k;
			s = a[p];
			t = a[q];
		}
	}
	printf("max = %d = %d * %d", max, m, n);
	printf("min = %d = %d * %d", min, s, t);
}

void main() {
	maxmin();
}

2.标志量的妙用

例题1(冒泡算法改进)

如果一串数据有序,还继续进行冒泡的话,就没有进行交换了,设置标志量flag,如果有序
就改变flag的值,不继续进行了
#include<stdio.h>

void effervescence() {
	int i, j, n, temp, flag, a[100];
	printf("input data number:");
	scanf("%d", &n);
	printf("input data:");
	for (i = 0; i < n; i++) {
		scanf("%d", a[i]);
	}

	flag = 1;
	for (i = 1; i <= n - 1 && flag == 1; i++) {		//flag != 1的话,就不满足条件,就退出了
		flag = 0;//flag = 0表示没进行过交换
		for (j = n - 1; j >= i; j--) {
			if (a[j] < a[j - 1]) {
				temp = a[j];
				a[j] = a[j - 1];
				a[j - 1] = temp;
				flag = 1;	//表示有交换
			}
		}
	}
	for (i = 0; i < n; i++) {
		printf("%d", a[i]);
	}
}

void main() {
	effervescence();
}

3.数字信息化

例题1

警察抓了a, b, c, d四名嫌疑犯,其中有一个人是小偷,
a说:我不是小偷
b说:c是小偷
c说:小偷肯定是d
d说:c在冤枉人
四个人中3个人说的是真话,问谁是小偷

转化:
a:x != 'a'
b:x == 'c'
c:x == 'd'
d:x != 'd'
#include<stdio.h>

void ceshi() {
	char x;
	for (x = 'a'; x <= 'd'; x++) {
		if (((x != 'a') + (x == 'c') + (x == 'd') + (x != 'd')) == 3) {
			printf("%c", x);
		}
	}
}

void main() {
	ceshi();
}

例题2

3位老师对某次数学竞赛进行了预测,他们的预测如下:
甲说:学生a得第一名,学生b得第三名
乙说:学生c得第一名,学生d得第四名
丙说:学生d得第三名,学生a得第三名
竞赛结果表明,他们都说对了一半,无并列名次,

转化:
甲:(a == 1) + (b == 3) = 1
乙:(c == 1) + (d == 4) = 1
丙:(d == 3) + (a == 3) = 1
#include<stdio.h>

void ceshi() {
	int a, b, c, d;
	for (a = 1; a <= 4; a++) {
		for (b = 1; b <= 4; b++) {
			if (a != b) {
				for (c = 1; c <= 4; c++) {
					if (c != a && c != b) {
						d = 10 - a - b - c;
						if (d != a && d != b && d != c) {
							if (((a == 1) + (b == 3)) == 1 && ((c == 1) + (d == 4)) == 1 && ((d == 3) + (a == 3)) == 1) {
								printf("%d, %d, %d, %d", a, b, c, d);
							}
						}
					}
				}
			}
		}
	}
}

void main() {
	ceshi();
}

例题3(是否整除)

编写算法对输入一个整数,判断能否被3, 5, 7整除,并输出一下信息之一:
能同时被3, 5, 7整除
能被其中两个数(指出是哪两个数)整除
能被其中一个数(指出是哪一个数)整除
不能被3, 5, 7中任一个整除
#include<stdio.h>

void judgment() {
	long n;
	int k;
	printf("Please enter a number:");
	scanf("%ld", &n);

	k = (n % 3 == 0) + (n % 5 == 0) + (n % 7 == 0);
	switch (k) {
	case 3: printf("all"); break;
	case 2: printf("two"); break;
	case 1: printf("one"); break;
	case 0: printf("none"); break;
	}
}

void main() {
	judgment();
}

系数为什么是1, 2, 4?

#include<stdio.h>

void judgment() {
	long n;
	int k;
	printf("Please enter a number:");
	scanf("%ld", &n);

	k = (n % 3 == 0) + (n % 5 == 0) * 2 + (n % 7 == 0) * 4;
	switch (k) {
	case 7: printf("all"); break;
	case 6: printf("5, 7"); break;
	case 5: printf("3, 7"); break;
	case 4: printf("7"); break;
	case 3: printf("3, 5"); break;
	case 2: printf("5"); break;
	case 1: printf("3"); break;
	case 0: printf("none"); break;
	}
}

void main() {
	judgment();
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值