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();
}