注册账号
1 条题解
-
0
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