代码改变世界

实用指南:洛谷题解——C语言(9.17——9.19)

2025-10-03 19:14  tlnshuju  阅读(4)  评论(0)    收藏  举报

1.B2112 石头剪子布

我的思路:

1.考虑读取输入:先用scanf()把第一行的整数读进来,然后注意到后边三行都是字符串形式,且无论两个player怎么出,字符串总长度都不会超过50,遂设置char s1[N][50]char s2[N][50] 。作为两个二维字符数组,分别存储N次游戏中两名玩家的选择(字符串长度不超过 50)。

2.循环遍历游戏:使用for循环,遍历N行的游戏次数,并同时利用scanf()读取每次player1和player2的选择。

3.考虑判断输赢:注意到使用strcmp()函数。

strcmp(s1, s2);
如果 s1 和 s2 是相同的,则返回 0;如果 s1<s2 则返回小于 0;如果 s1>s2 则返回大于 0。

其中,用if ,else if, else判断语句先考虑平局的情况,然后再根据规则分别写出所有player1赢的可能,最后else则player2赢。

4.程序退出:return 0  主函数退出。

完整代码:

int main() {
    int N;
    scanf("%d", &N);  // 读取游戏次数N
    char s1[N][50] ;  // 存储N次游戏中Player1的选择(每个选择是字符串,长度≤50)
    char s2[N][50] ;  // 存储N次游戏中Player2的选择
    for (int j = 0; j < N; j++) {  // 循环处理每次游戏
        scanf("%s %s", s1[j], s2[j]);  // 读取本次Player1和Player2的选择
        // 情况1:两人选择相同 → 平局
        if (strcmp(s1[j], s2[j]) == 0) {
            printf("Tie\n");
        }
        // 情况2:Player1胜利的三种规则
        else if ((strcmp(s1[j], "Rock") == 0 && strcmp(s2[j], "Scissors") == 0) ||
                 (strcmp(s1[j], "Scissors") == 0 && strcmp(s2[j], "Paper") == 0) ||
                 (strcmp(s1[j], "Paper") == 0 && strcmp(s2[j], "Rock") == 0)) {
            printf("Player1\n");
        }
        // 情况3:其余情况(Player2胜利)
        else {
            printf("Player2\n");
        }
    }
    return 0;  // 程序正常结束
}

2.B2094 不与最大数相同的数字之和

我的思路:

1.考虑读取输入:先用scanf()将第一行的整数N读进来,然后注意到第二行是一个数组形式,即用for循环读取N个整数到数组arr[]中,再输入arr[]。

2.寻找最大数:因为题目要求输出一个整数数列中不与最大数相同的数字之和,所以考虑通过遍历数组,mark到这个最大数。即初始化一个max在数组中等于0,运用for循环,让arr[i]中一旦大于max就把这个值赋予max,通过不断更新最大值即可找到最大值。

3.累加数字without最大数:先初始化变量sum,再次遍历整个数组,使用判断语句,如果数组里的数!=max,则累加进sum。

4.输出结果:printf("%d",sum);

5.程序退出:return 0  主函数退出。

完整代码:

#include 
int main() {
    int N;
    scanf("%d", &N);  // 步骤1:读取整数的个数N
    int arr[N];
    for (int i = 0; i < N; i++) {
        scanf("%d", &arr[i]);  // 步骤1:读取N个整数到数组arr中
    }
    int max = arr[0];
    for (int i = 0; i < N; i++) {
        if (arr[i] > max) {
            max = arr[i];  // 步骤2:遍历数组,找到最大值max
        }
    }
    int sum = 0;
    for (int i = 0; i < N; i++) {
        if (arr[i] != max) {
            sum += arr[i];  // 步骤3:累加所有不等于max的数字
        }
    }
    printf("%d", sum);  // 输出最终的累加和
    return 0;
}

3.B2095 白细胞计数

我的思路:(错误版)

1.考虑读取输入:先用scanf()将第一n读进来,然后将后边几行用for循环读取n行到数组arr[]中,再输入arr[]。

2.找最大和最小值:因为题目要求去掉一个最小值和最大值,所以先各初始化变量min1和max1为arr[0],分别利用for循环遍历数组,一旦发现数组中比他大/小的值就赋给max/min,通过如此更新找到最大/最小值。

3.去掉最大/最小值并取平均值(错误点1)通过简单的判断语句,如果数值不等于最大/最小值,则累加数值和并计数,分别得到sum和count,接着用sum/count求出平均值。

4.求误差(错误点2)先初始化误差为0,同样遍历判断语句除去最大最小值的循环,然后使用fabs函数取绝对值,再将每次求出的绝对值进行循环遍历更新,找到最大的误差并输出。

5.程序退出:return 0  主函数退出。

我的代码:(错误版)

#include 
#include 
int main() {
	int n;
	scanf("%d", &n);
	float arr[320];
	for (int i = 0; i < n; i++) {
		scanf("%f", &arr[i]);
	}
	float max1 = arr[0];
	for (int i = 1; i < n; i++) {
		if (arr[i] > max1) {
			max1 = arr[i];
		}
	}
	float min1 = arr[0];
	for (int i = 1; i < n; i++) {
		if (arr[i] < min1) {
			min1 = arr[i];
		}
	}
	float a = 0;
	float sum = 0;
	int count = 0;
	for (int i = 0; i < n; i++) {
		if (arr[i] != max1 && arr[i] != min1) {
			sum += arr[i];
			count++;
		}
	}
	a = sum / count;
	float maxd = 0;
	for (int i = 0; i < n; i++) {
		if (arr[i] != max1 && arr[i] != min1) {
			float d = fabs(arr[i] - a);
			if (d > maxd) {
				maxd = d;
			}
		}
	}
	printf("%.2f %.2f", a, maxd);
	return 0;
}

错误原因:

for (int i = 0; i < n; i++) {
        if (arr[i] != max1 && arr[i] != min1) {
            sum += arr[i];
            count++;
        }
    }

for (int i = 0; i < n; i++) {
        if (arr[i] != max1 && arr[i] != min1) {
            float d = fabs(arr[i] - a);
            if (d > maxd) {
                maxd = d;
            }
        }
    }

以上两块的除去最大最小值存在漏洞,即当数组中存在多个相同的最大值多个相同的最小值时,会错误地排除所有等于最大值 / 最小值的元素,而实际需求应该是仅排除一个最大值和一个最小值(无论其重复次数)。

修改方案:

  1. 计算总和:先求出所有元素的总totalsum,避免遍历筛选时误删多个极值。
  2. 仅排除一个最大值和一个最小值:通过 总和 - 最大值 - 最小值 得到有效总和,有效个数为 n - 2(当n>=2)
  3. 计算误差时跳过一个极值:遍历数组时,仅跳过一个最大值和一个最小值,其余元素参与误差计算。(增加初始化标记skipmax/skipmin=0,循环如果找到过一个最大值/最小值则变成1,使其跳过这个元素,continue循环,通过其0/1的mark避免排除多个极值)。

修改后代码:

#include 
#include 
int main() {
	int n;
	scanf("%d", &n);
	float totalsum = 0;
	float arr[320];
	for (int i = 0; i < n; i++) {
		scanf("%f", &arr[i]);
		totalsum += arr[i];
	}
	float max1 = arr[0];
	for (int i = 1; i < n; i++) {
		if (arr[i] > max1) {
			max1 = arr[i];
		}
	}
	float min1 = arr[0];
	for (int i = 1; i < n; i++) {
		if (arr[i] < min1) {
			min1 = arr[i];
		}
	}
	float sum = totalsum - max1 - min1;
	int count = n - 2;
	float a = sum / count;
	float maxd = 0;
	int skipmax = 0;// 标记是否已跳过一个max1
	int skipmin = 0;// 标记是否已跳过一个min1
	for (int i = 0; i < n; i++) {
    // 若当前元素是max1且未跳过,则跳过并标记
		if (arr[i] == max1 && skipmax == 0) {
			skipmax = 1;
			continue;
		}
    // 若当前元素是min1且未跳过,则跳过并标记
		if (arr[i] == min1 && skipmin == 0) {
			skipmin = 1;
			continue;
		}
		float d = fabs(arr[i] - a);
		if (d > maxd) {
			maxd = d;
		}
	}
	printf("%.2f %.2f", a, maxd);
	return 0;
}

​​​​​​​