小红比身高
[题目链接](https://www.nowcoder.com/practice/4722fa5316a543b8b4e7c0d1bdf64942)
思路
小红可以自由选择站在哪阶楼梯上,她的总高度 = 自身身高 + 所选楼梯高度。要使她比尽可能多的朋友高,显然应该选择高度最大的楼梯。
具体步骤
- 计算每个朋友的总高度:朋友
的总高度 =
,其中
是朋友身高,
是朋友所站楼梯的高度。
- 选择最高的楼梯:小红的总高度 =
。
- 统计严格小于小红总高度的朋友数:将所有朋友的总高度排序后,用二分查找找到第一个
小红总高度的位置,该位置的下标即为答案。
为什么选最高楼梯一定最优?
小红的总高度越大,能比过的朋友越多。楼梯的选择只影响小红自己的高度,不影响朋友的高度,因此直接取最大楼梯高度即可。
复杂度分析
- 时间复杂度:
,排序朋友总高度的开销占主导。
- 空间复杂度:
,存储朋友和楼梯信息。
代码
[sol-C++]
#include <bits/stdc++.h>
using namespace std;
int main(){
int n, m;
long long h;
scanf("%d%d%lld", &n, &m, &h);
vector<long long> a(n), p(n), s(m);
for(int i = 0; i < n; i++) scanf("%lld", &a[i]);
for(int i = 0; i < n; i++) scanf("%lld", &p[i]);
for(int i = 0; i < m; i++) scanf("%lld", &s[i]);
vector<long long> tot(n);
for(int i = 0; i < n; i++){
tot[i] = a[i] + s[p[i]-1];
}
sort(tot.begin(), tot.end());
long long maxS = *max_element(s.begin(), s.end());
long long myH = h + maxS;
// count friends with tot[i] < myH
int ans = (int)(lower_bound(tot.begin(), tot.end(), myH) - tot.begin());
printf("%d\n", ans);
return 0;
}
[sol-Java]
import java.util.*;
import java.io.*;
public class Main {
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int n = Integer.parseInt(st.nextToken());
int m = Integer.parseInt(st.nextToken());
long h = Long.parseLong(st.nextToken());
long[] a = new long[n];
st = new StringTokenizer(br.readLine());
for (int i = 0; i < n; i++) a[i] = Long.parseLong(st.nextToken());
int[] p = new int[n];
st = new StringTokenizer(br.readLine());
for (int i = 0; i < n; i++) p[i] = Integer.parseInt(st.nextToken());
long[] s = new long[m];
st = new StringTokenizer(br.readLine());
for (int i = 0; i < m; i++) s[i] = Long.parseLong(st.nextToken());
long[] tot = new long[n];
for (int i = 0; i < n; i++) {
tot[i] = a[i] + s[p[i] - 1];
}
Arrays.sort(tot);
long maxS = s[0];
for (long v : s) maxS = Math.max(maxS, v);
long myH = h + maxS;
// binary search: count tot[i] < myH
int lo = 0, hi = n;
while (lo < hi) {
int mid = (lo + hi) / 2;
if (tot[mid] < myH) lo = mid + 1;
else hi = mid;
}
System.out.println(lo);
}
}
[sol-Python3]
import sys
from bisect import bisect_left
input = sys.stdin.readline
n, m, h = map(int, input().split())
a = list(map(int, input().split()))
p = list(map(int, input().split()))
s = list(map(int, input().split()))
tot = sorted(a[i] + s[p[i] - 1] for i in range(n))
my_h = h + max(s)
print(bisect_left(tot, my_h))
[sol-JavaScript]
const readline = require('readline');
const rl = readline.createInterface({ input: process.stdin });
const lines = [];
rl.on('line', line => lines.push(line.trim()));
rl.on('close', () => {
const [n, m, h] = lines[0].split(' ').map(Number);
const a = lines[1].split(' ').map(Number);
const p = lines[2].split(' ').map(Number);
const s = lines[3].split(' ').map(Number);
const tot = [];
for (let i = 0; i < n; i++) {
tot.push(a[i] + s[p[i] - 1]);
}
tot.sort((x, y) => x - y);
const maxS = Math.max(...s);
const myH = h + maxS;
// binary search: count tot[i] < myH
let lo = 0, hi = n;
while (lo < hi) {
const mid = (lo + hi) >> 1;
if (tot[mid] < myH) lo = mid + 1;
else hi = mid;
}
console.log(lo);
});

京公网安备 11010502036488号