基準点以上の 受験者の人数
- 二分探索
- 問題 09
- ふつう
- 目安 31 分
低い順に
本番の
入力は
問題
社内の
入力の形式
N
a_1 a_2 ... a_N
Q
x_1
x_2
...
x_Q1 行目に
出力の形式
Q 行を
制約
- N と Q は、
どちらも 1 以上 200000 以下です - 点数 a_i は、
0 以上 1000000 以下の整数です - 点数は
低い順に 並んでいます。 a_1 は a_2 以下、 a_2 は a_3 以下、と 続き、 a_(N-1) は a_N 以下です - 基準点 x_k は、
0 以上 1000000 以下の整数です
入力と出力の例
例 1
6 人の
入力
6 40 55 60 60 72 90 4 60 91 0 56
出力
4 0 6 4
例 2
受験者が
入力
1 70 2 70 71
出力
1 0
ヒント
まだ開いていません
付箋は 3 枚。下の段ほど答えに近づきます
ヒント 2
ヒント 3答えに近い
全部の
先に
解答
点数の
Python
Python
import sys
from bisect import bisect_left
data = sys.stdin.read().split()
n = int(data[0])
scores = list(map(int, data[1:1 + n]))
q = int(data[1 + n])
queries = list(map(int, data[2 + n:2 + n + q]))
answers = [n - bisect_left(scores, x) for x in queries]
print("\n".join(map(str, answers)))JavaScript
JavaScript
const data = require("fs").readFileSync(0, "utf8").split(/\s+/).filter(Boolean).map(Number);
const n = data[0];
const scores = data.slice(1, 1 + n);
const q = data[1 + n];
const queries = data.slice(2 + n, 2 + n + q);
// x 以上になる最初の位置。どの点数も x より小さければ n
function lowerBound(x) {
let low = 0;
let high = n;
while (low < high) {
const mid = (low + high) >> 1;
if (scores[mid] < x) {
low = mid + 1;
} else {
high = mid;
}
}
return low;
}
const answers = queries.map((x) => n - lowerBound(x));
console.log(answers.join("\n"));計算量
時間は O(N + Q log N) です。sum(1 for a in scores if a >= x) のように 1 行で
よく ある間違い
- 「x より大きい」と
「x 以上」を 取り違える。 x 点ちょうどの 人も 数えるので、 x 以上に なる 最初の 位置を 探します。 Python では bisect_rightではなくbisect_leftです - 同じ
点数の 人が 何人も 並ぶときに、 見つけた 1 人の 位置を そのまま 使ってしまう。 二分探索は 「x 以上に なる 最初の 位置」を 探すように書きます - x が
どの 点数より 大きい ときの 答えを 0 に し忘れる。 探す範囲の 右端を N - 1 ではなく N に しておくと、 位置が N に なって 自然に 0 が出ます - 答えを 1 つずつ print して
出力が 遅くなる。 Q が 20 万行なら、 まとめて 1 回で 出力する ほうが 速く書けます
解答を動かした版 Python 3.12.14Node.js 22.23.4確認日 2026/10/31