文章

【GESP】C++三级练习 luogu-P5728 【深基5.例5】旗鼓相当的对手

GESP C++三级练习,一维数组联系,难度★★☆☆☆。

luogu-P5728 【深基5.例5】旗鼓相当的对手

题目要求

题目描述

现有 $N$ 名同学参加了期末考试,并且获得了每名同学的信息:语文、数学、英语成绩(均为不超过 $150$ 的自然数)。如果某对学生 $(i,j)$ 的每一科成绩的分差都不大于 $5$,且总分分差不大于 $10$,那么这对学生就是“旗鼓相当的对手”。现在想知道这些同学中,有几对“旗鼓相当的对手”?同样一个人可能会和其他好几名同学结对。

输入格式

第一行一个正整数 $N$。

接下来 $N$ 行,每行三个整数,其中第 $i$ 行表示第 $i$ 名同学的语文、数学、英语成绩。最先读入的同学编号为 $1$。

输出格式

输出一个整数,表示“旗鼓相当的对手”的对数。

输入输出样例 #1

输入 #1

1
2
3
4
3
90 90 90
85 95 90
80 100 91

输出 #1

1
2

说明/提示

数据保证,$2 \le N\le 1000$ 且每科成绩为不超过 $150$ 的自然数。


题目分析

解题思路

本题的解题思路如下:

  1. 问题分析:
    • 输入学生总数 $N$($2 \le N \le 1000$)
    • 每个学生有三科成绩:语文、数学、英语(均为不超过150的自然数)
    • 需要找出”旗鼓相当的对手”对数
  2. 解题方法:
    • 核心思路:
      • 使用三个数组分别存储三科成绩
      • 双重循环遍历所有可能的学生对
      • 判断每对学生是否满足”旗鼓相当”条件
    • 实现方式:
      • 读取N和所有学生成绩
      • 遍历所有可能的学生对(i,j),其中j>i避免重复
      • 检查该对学生是否满足条件并计数
  3. 实现要点:
    • 旗鼓相当的条件:
      • 每科成绩分差不超过5分
      • 总分差不超过10分
    • 需要使用绝对值函数计算分差
    • 注意数组大小要根据输入的N来定义

注:本题可以是用一个二维数组来存储所有学生的成绩,然后使用双重循环遍历所有可能的学生对。但是考虑到二维数组非3级大纲范围内要求,因此特意用3个一维数组实现。

复杂度分析:

  • 时间复杂度:$O(N^2)$,其中N为学生总数
  • 空间复杂度:$O(N)$,需要存储N个学生的三科成绩


示例代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <cmath>
#include <iostream>

int main() {
    // 读取学生人数N
    int N;
    std::cin >> N;
    
    // 定义三个数组分别存储语文、数学、英语成绩
    int one_ary[N];   // 语文成绩数组
    int two_ary[N];   // 数学成绩数组
    int three_ary[N]; // 英语成绩数组
    
    // 读入每个学生的三科成绩
    for (int i = 0; i < N; i++) {
        std::cin >> one_ary[i] >> two_ary[i] >> three_ary[i];
    }
    
    // 统计旗鼓相当对手的对数
    int count = 0;
    
    // 双重循环遍历所有可能的学生对
    for (int i = 0; i < N; i++) {
        for (int j = i + 1; j < N; j++) {
            // 判断是否为旗鼓相当的对手:
            // 1. 每科分差不超过5分
            // 2. 总分差不超过10分
            if (std::abs(one_ary[j] - one_ary[i]) <= 5 &&
                std::abs(two_ary[j] - two_ary[i]) <= 5 &&
                std::abs(three_ary[j] - three_ary[i]) <= 5 &&
                std::abs(one_ary[i] + two_ary[i] + three_ary[i] -
                         (one_ary[j] + two_ary[j] + three_ary[j])) <= 10) {
                count++;
            }
        }
    }
    
    // 输出结果
    std::cout << count << std::endl;
    return 0;
}

所有代码已上传至Github:https://github.com/lihongzheshuai/yummy-code

GESP各级别考纲要点、知识拓展和练习题目清单详见C++学习项目主页

luogu-”系列题目已加入洛谷Java、C++初学团队作业清单,可在线评测,团队名额有限,欢迎加入。

bcqm-”系列题目可在编程启蒙题库进行在线评测。

本文由作者按照 CC BY 4.0 进行授权