2 条题解

  • 0
    @ 2025-5-25 22:48:59

    题目描述

    现在需要为本地业余篮球联赛的五支球队(蚂蚁队、桶队、猫队、运球者队、大象队,分别对应字母 A、B、C、D、E)确定季前赛的中位数排名。中位数排名的定义是:与所有给定排名的距离之和最小的排名。若存在多个这样的排名,选择按字母顺序最小的那个。

    距离的计算方式:两个排名之间的距离等于所有球队对中相对顺序不同的对数。例如,排名 ACDBE 和 ABCDE 中,球队对 (B,C) 和 (B,D) 的顺序不同,因此距离为 2。

    输入输出要求:

    输入包含多个测试用例,每个用例第一行是整数 n(n≤100),随后 n 行是五个字母的排列(代表 n 个专家的排名)。 输出每个用例的中位数排名及其距离总和。若有多个解,输出字典序最小的。 解题思路

    1. 问题分析 我们需要枚举所有可能的五支球队的排列(共 5!=120 种可能),计算每个排列与所有输入排名的距离之和,找到总和最小的排列。若有多个最小值,选择字典序最小的排列。
    2. 关键步骤 2.1 生成所有可能的排列 五支球队的排列共有 120 种,可以通过预先生成所有排列并按字典序排序,以便后续处理时直接遍历并比较字典序。 2.2 计算两个排名之间的距离 对于两个排列 A 和 B,计算所有球队对 (i,j) 中在 A 和 B 中顺序不同的对数。具体步骤如下:

    对每个球队对 (i,j)(i≠j),检查在 A 中 i 是否在 j 前面,同时在 B 中 i 是否在 j 后面,或者反之。若顺序不同,则计数加 1。 2.3 枚举所有候选排列并计算总距离 遍历所有 120 种排列,对每个排列计算其与所有输入排名的距离之和。记录当前最小总距离及对应的排列。若遇到总距离相同的排列,比较字典序,保留较小的那个。 3. 实现细节 3.1 生成排列的字典序顺序 可以使用 Python 的itertools.permutations生成所有排列,然后将其转换为字符串形式(如 "ABCDE"),并按字典序排序,确保在枚举时按字典序顺序处理,以便在总距离相同时自动选择字典序最小的排列。 3.2 距离计算函数 定义一个函数distance(rank1, rank2),计算两个长度为 5 的字符串之间的距离。通过双重循环遍历所有球队对,比较它们在两个字符串中的顺序是否不同。 3.3 处理输入输出 读取每个测试用例的 n 个排名,对每个候选排列计算总距离,更新最小总距离和对应的最优排列。最后输出结果。 4. 复杂度分析 每个测试用例需要枚举 120 种排列,每个排列需要与 n 个输入排名计算距离。 计算两个排名的距离的时间复杂度为 O (5×4)=O (20)(因为共有 5×4/2=10 对球队,但双重循环遍历所有 i<j 的对共 10 次)。 总时间复杂度为 O (120×n×20) = O (2400n),对于 n≤100 来说,完全可行。 示例代码 python

    import itertools
    
    def calculate_distance(rank1, rank2):
        distance = 0
        for i in range(5):
            for j in range(i+1, 5):
                a = rank1[i]
                b = rank1[j]
                # 在rank2中查找a和b的位置
                pos1 = rank2.index(a)
                pos2 = rank2.index(b)
                if (pos1 > pos2) != (i > j):
                    distance += 1
        return distance
    
    def find_median_ranking(input_ranks):
        # 生成所有可能的排列,按字典序排序
        teams = ['A', 'B', 'C', 'D', 'E']
        all_permutations = [''.join(p) for p in itertools.permutations(teams)]
        all_permutations.sort()  # 确保按字典序处理
        
        min_total = float('inf')
        best_rank = None
        
        for candidate in all_permutations:
            total = 0
            for rank in input_ranks:
                total += calculate_distance(candidate, rank)
            if total < min_total or (total == min_total and candidate < best_rank):
                min_total = total
                best_rank = candidate
        return best_rank, min_total
    
    def main():
        import sys
        input = sys.stdin.read().split()
        ptr = 0
        while True:
            n = int(input[ptr])
            ptr += 1
            if n == 0:
                break
            input_ranks = []
            for _ in range(n):
                rank = input[ptr]
                ptr += 1
                input_ranks.append(rank)
            best, value = find_median_ranking(input_ranks)
            print(f"{best} is the median ranking with value {value}.")
    
    if __name__ == "__main__":
        main()
    

    代码解释 calculate_distance函数:计算两个排名之间的距离,通过遍历所有球队对并比较顺序差异。 find_median_ranking函数:生成所有排列并按字典序排序,遍历每个候选排列,计算其与所有输入排名的总距离,更新最小总距离和最优排列(确保字典序最小)。 main函数:读取输入数据,处理每个测试用例,调用上述函数求解并输出结果。

    该方法通过枚举所有可能的排列并按字典序处理,确保在总距离相同时选择字典序最小的解,满足题目要求。

    • 0
      @ 2025-5-5 12:25:05

      题意分析

      本题的核心是在给定的多个由字母 A、B、C、D、E 组成的球队排名(代表蚂蚁队、桶队、猫队、运球者队和大象队的排名)中,找到一个中位数排名。中位数排名的定义是与所有给定排名的距离之和最小的排名,其中两个排名之间的距离是指两队之间相对顺序不同的总对数。需要处理多个输入集,每个输入集先输入排名的数量 n,然后是 n 个具体的排名,以输入 0 表示所有输入结束。最终输出每个输入集对应的中位数排名及其值,若有多个中位数排名,输出按字母顺序排在前面的那个。

      解题思路

      1. 输入处理:读取每个输入集的排名数量 n,然后依次读取 n 个由字母 A、B、C、D、E 组成的排名字符串,存储在数组 a 中。
      2. 生成所有可能的排名:使用 next_permutation 函数对初始排名字符串 s = "ABCDE" 进行全排列,遍历所有可能的排名情况。
      3. 计算距离和:对于每个生成的排名 s,遍历输入的 n 个排名 a[i],对于每个 a[i],再遍历其中的每一对字母(共 C(5, 2) = 10 对),在当前生成的排名 s 中找到这两个字母的位置 tjtk,若 tj > tk,则说明在这两个排名中这对字母的相对顺序不同,距离和 count 加 1。计算完 s 与所有输入排名的距离和 count 后,与当前最小距离和 js 比较。
      4. 更新中位数排名:若 count < js,则更新最小距离和 jscount,并将当前排名 s 更新为中位数排名 jg
      5. 输出结果:遍历完所有可能的排名后,输出中位数排名 jg 及其最小距离和 js,格式为 ranking is the median ranking with value value.

      复杂度分析

      1. 时间复杂度
        • 输入部分,读取 n 个排名,时间复杂度为 \(O(n)\),其中 n 是每个输入集中排名的数量。
        • 生成所有可能的排名,next_permutation 函数生成全排列的时间复杂度为 \(O(5!)\),对于每个生成的排名,需要计算与 n 个输入排名的距离,计算距离的过程中,对于每个输入排名有 \(C(5, 2) = 10\) 对字母需要比较,所以计算距离的时间复杂度为 \(O(n \times 10)\)。因此,总的时间复杂度为 \(O(5! \times n \times 10)\),在 n 不超过 100 的情况下,该算法在可接受的时间范围内。
      2. 空间复杂度
        • 存储输入的 n 个排名需要 \(O(n)\) 的空间,存储生成的排名以及中间变量等额外空间为常数级,所以总的空间复杂度为 \(O(n)\)

      代码实现

      #include <iostream>
      #include <string>
      #include <algorithm>
      #include <cstdio>
      using namespace std;
      
      string a[108];
      
      int main() {
          while (1) {
              int n;
              cin >> n;
              if (n == 0) {
                  break;
              }
              for (int i = 0; i < n; i++) {
                  cin >> a[i];
              }
              string s = "ABCDE";
              string jg = "ABCDE";
              int js = 1000;
              do {
                  int count = 0;
                  for (int i = 0; i < n; i++) {
                      for (int j = 0; j < 5; j++) {
                          for (int k = j + 1; k < 5; k++) {
                              char x = a[i][j];
                              char y = a[i][k];
                              int tj, tk;
                              for (int h = 0; h < 5; h++) {
                                  if (s[h] == x) {
                                      tj = h;
                                  }
                                  if (s[h] == y) {
                                      tk = h;
                                  }
                              }
                              if (tj > tk) {
                                  count++;
                              }
                          }
                      }
                  }
                  if (count < js) {
                      js = count;
                      jg = s;
                  }
              } while (next_permutation(s.begin(), s.end()));
              cout << jg << " is the median ranking with value " << js << "." << endl;
          }
          return 0;
      }
      
      • 1

      信息

      ID
      1039
      时间
      1000ms
      内存
      256MiB
      难度
      10
      标签
      递交数
      2
      已通过
      2
      上传者