top1编程
← 返回题目
题解

注册账号

1 条题解

  • 0
    @ 2026-8-5 23:54:04

    P4632 注册账号(基础)

    解题思路

    这道题要同时处理两类账号,分五步来做。

    第一步,分清两类账号。 每个人有两个信息:账号类型和账号内容。类型 i 表示身份证号,类型 q 表示 QQ 号。身份证号要用来判断男女性别,QQ 号要用来求平均值。

    第二步,从身份证号判断性别。 18 位身份证号的第 17 位(倒数第二位)是性别位:奇数代表男性,偶数代表女性。比如号码 51170219740419175X,从左往右数第 17 位是数字 5,是奇数,所以是男性。注意身份证号可能以字母 X 结尾,但 X 只是校验位,不影响第 17 位,我们只需要看第 17 个字符。代码里写成 idCard[16],因为数组下标从 0 开始,第 17 个字符正好在位置 16。

    第三步,用 long long 存 QQ 号。 QQ 号是一串可能很长的数字,比如样例里的 34012459,有的甚至十几位,用普通 int 存不下,所以要用 long long 类型。把所有 QQ 号累加到总和变量,同时记录 QQ 号的个数,最后总和除以个数就是平均值。

    第四步,用结构体把账号信息装好。 结构体 Account 把"账号类型"和"QQ 号数值"装在一起,读入和存放一目了然。身份证号只关心第 17 位,直接判断即可,不必完整保存。

    第五步,注意输出格式和除以 0。 输出保留 3 位小数,用 printf 的 %.3f,它会自动四舍五入。比如样例两个 QQ 号 505165 和 34012459,平均值 17258812,输出 17258812.000。还要小心:如果 N 个人全是身份证号,没有 QQ 号,个数为 0,平均值按 0.000 输出,程序要加判断避免除以 0。

    **回顾总结。**这道题把两种任务合在一起:平均值保留三位小数,输出时小数点后不足三位会自动补 0。身份证号看第 17 位的奇偶判断性别,QQ 号累加求平均。要点有三个——第 17 位用 idCard[16] 取、QQ 号用 long long 存、QQ 号个数为 0 时特判平均值。每类账号各走各的分支,逻辑清爽。

    参考代码

    // 程序用途:统计身份证男女人数,并求QQ号平均值(保留3位小数)
    #include <iostream>
    #include <cstdio>
    using namespace std;
    
    struct Account {
        char type;          // 账号类型:i 身份证 / q QQ号
        long long qqNumber; // QQ号的数值(身份证账号不用)
    };
    
    int main() {
        int n;
        cin >> n;
        int male = 0, female = 0;   // 男女人数
        long long qqSum = 0;        // 所有QQ号整数精确累加
        int qqCount = 0;            // QQ号个数
        struct Account accounts[10005];
        for (int i = 0; i < n; i++) {
            cin >> accounts[i].type;
            if (accounts[i].type == 'i') {      // 身份证号:看第17位判断性别
                char idCard[20];
                cin >> idCard;
                if ((idCard[16] - '0') % 2 == 1) male++;  // 第17位是奇数则为男
                else female++;                            // 第17位是偶数则为女
            } else {                            // QQ号:累加求平均
                cin >> accounts[i].qqNumber;
                qqSum += accounts[i].qqNumber;
                qqCount++;
            }
        }
        double avg = (qqCount == 0) ? 0.0 : (double)qqSum / qqCount;  // 求平均值,防止除以0
        printf("%d %d %.3f\n", male, female, avg);  // 保留3位小数输出
        return 0;
    }
    

    复杂度分析

    时间上,程序对 N 个账号逐个读入并处理,每个账号只做一次判断或累加,总共执行的次数和 N 成正比,所以时间复杂度是 O(N)。空间上,我们用一个大小固定的结构体数组存放账号信息,数组大小根据题目最大数据量来确定,所以空间复杂度是 O(N)。本题 N 最大可达 10000,这样的算法在 1 秒内轻松完成,没有任何压力。

    • 1