- 有一个班级有 n 个人,给出 n 个元素,第 i 个元素代表 第 i 位同学的考试成绩,接下进行 m 次询问,每次询问给出一个数值 t ,表示第 t 个同学,然后需要我们输出第 t 个同学的成绩超过班级百分之几的人,百分数 p 可以这样算:p = (不超过第 t 个同学分数的人数 ) / n * 100%。输出的时候保留到小数点后 6 位,并且需要四舍五入。
-
- 输入描述:第一行输入两个数 n 和 m,两个数以空格隔开,表示 n 个同学和 m 次询问。第二行输入 n 个数值 ni,表示每个同学的分数,第三行输入 m 个数值mi,表示每次询问是询问第几个同学。(注意,这里 2<=n,m<=100000,0<=ni<=150,1<=mi<=n)
-
- 输出描述:输出 m 行,每一行输出一个百分数 p,代表超过班级百分之几的人。
-
- 示例1:
-
- 输入 :
-
- 3 2
-
- 50 60 70
-
- 1 2
-
- 输出
-
- 33.333333%
-
- 66.666667%
一开始我的思路是,先将 scores 数组排序,这样就能很容易算出 “有多少人不超过当前分数” 这个前缀和。但如果要将 scores 排序的话,还得另外记录 “第 mi 位同学” 排序后是第几位,这样就很麻烦,一点都不优雅。
今天看到 lucifer 的公众号推文后,才发现原来可以把“分数”这个值本身当作数组下标啊,所以思路就变成了:
分数的范围是 [0, 150],所以我们可以用一个长度为 150 的数组 prefix 来记录每个分数出现的次数,数组下标是分数值,数组的值就是分数出现的 次数;scores 数组,对于每个分数 s,prefix[s]++;prefix,计算前缀和;mi 位同学的分数能超过班上百分之几的人scores[mi] 找到这位同学的分数 sprefix[s] 找到不超过分数 s 的人数JavaScript Code
/**
* @param {number[]} scores 全班同学的分数
* @param {number} mi 第 mi 个同学
* @return {number} 第 mi 个同学的分数能超过班级百分之几的人
*/
var test = function (scores, mi) {
// 下标是分数,值是“有多少人是这个分数”
const prefix = Array(151).fill(0);
// 先遍历 scores 数组,统计每个分数的人数
scores.forEach(s => prefix[s]++);
// 计算前缀和
// 下标是分数,值是“有多少人不超过这个分数 <=”
for (let i = 1; i < prefix.length; i++) {
prefix[i] += prefix[i - 1];
}
// 第 mi 个同学的分数
const score = scores[mi - 1];
const p = (prefix[score] / scores.length) * 100;
return p.toFixed(6) + '%';
};
const __main__ = function () {
const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
console.log('******输入******');
rl.prompt();
const inputs = [];
rl.on('line', line => inputs.push(line));
rl.on('close', () => {
const [n, m] = inputs[0].split(' '); // n 个同学, m 次询问
const scores = inputs[1].split(' ').slice(0, n); // 全班同学的分数
const asks = inputs[2].split(' ').slice(0, m); // 每次询问的是第几位同学
console.log('\n******输出******');
asks.forEach(mi => {
const p = test(scores, mi);
console.log(p);
});
});
};