题解:洛谷 P1781 宇宙总统

【题目来源】

洛谷:P1781 宇宙总统 - 洛谷(luogu.com.cn)

【题目描述】

地球历公元 \(6036\) 年,全宇宙准备竞选一个最贤能的人当总统,共有 \(n\) 个非凡拔尖的人竞选总统,现在票数已经统计完毕,请你算出谁能够当上总统。

【输入】

第一行为一个整数 \(n\),代表竞选总统的人数。

接下来有 \(n\) 行,分别为第一个候选人到第 \(n\) 个候选人的票数。

【输出】

共两行,第一行是一个整数 \(m\),为当上总统的人的号数。

第二行是当上总统的人的选票。

【输入样例】

5
98765
12365
87954
1022356
985678

【输出样例】

4
1022356

【核心思想】

  1. 问题分析:有 \(n\) 名候选人,每人的票数是一个可能长达 100 位的大整数。需要找出票数最多的候选人,输出其编号和票数。由于票数可能超出 64 位整数范围,不能直接使用数值比较,必须使用字符串比较:先比较长度(位数多则数值大),长度相同再按字典序比较。

  2. 算法选择

    • 字符串比较:以字符串形式读入票数。维护当前最大票数字符串 max 和对应候选人编号 mark。对于每个新读入的字符串 s,若 s.length() > max.length(),或长度相等且 s > max(字典序),则更新 maxmark
    • 复杂度\(O(n \times L)\),其中 \(L\) 是票数的最大长度(\(\le 100\)),\(n\) 为候选人数量。
  3. 关键步骤

    • 读入:读取 \(n\),然后循环 \(n\) 次,每次读入一个票数字符串 s
    • 比较与更新:若 s.length() > max.length() 或 (s.length() == max.length()s > max),则更新 max = smark = i
    • 输出:输出 markmax
  4. 时间/空间复杂度

    • 时间复杂度:\(O(n \times L)\)\(L \le 100\)
    • 空间复杂度:\(O(L)\)
  5. 大数比较与字符串

    • 位数优先:比较两个大整数时,位数多的必然更大。
    • 字典序比较:当位数相同时,字符串的字典序比较等同于数值比较(因为数字字符串长度相同且无前导零)。
    • 适用场景:当处理超出基本整数类型的大整数比较时,字符串比较是最简单有效的方法。

【算法标签】

普及- #字符串入门

【代码详解】

#include <bits/stdc++.h>
using namespace std;

int main() {
    string max = "0", s; // max: 当前最大的数字字符串,s: 临时存储输入的字符串
    int len1, len2, mark = 1, n; // len1: max的长度,len2: s的长度,mark: 最大数字的位置,n: 输入的数字个数
    cin >> n; // 输入数字的个数

    for (int i = 1; i <= n; i++) {
        cin >> s; // 输入一个数字字符串
        len1 = max.size(); // 获取当前最大数字字符串的长度
        len2 = s.size();   // 获取当前输入数字字符串的长度

        // 比较规则:
        // 1. 如果当前输入的数字字符串长度更长,则更新最大值和位置
        if (len1 < len2) {
            mark = i; // 记录当前数字的位置
            max = s;  // 更新最大值
        }
        // 2. 如果长度相同,按字典序比较,如果当前输入的数字字符串更大,则更新最大值和位置
        else if (len1 == len2 && max < s) {
            mark = i; // 记录当前数字的位置
            max = s;  // 更新最大值
        }
    }

    // 输出结果
    cout << mark << endl << max; // 输出最大数字的位置和最大数字
    return 0;
}

【运行结果】

5
98765
12365
87954
1022356
985678
4
1022356
posted @ 2026-08-31 09:25  团爸讲算法  阅读(11)  评论(0)    收藏  举报