链接:https://ac.nowcoder.com/acm/problem/213483
来源:牛客网
题目描述
给定一个数组a,以及两个正整数 和 ,求取两个数 和 aja_jaj ,满足的取法有多少种?
注:只要两个取法有一个角标不同,则视为两种不同的取法。
输入描述:
第一行有三个正整数,,,分别代表数组长度,和的下界和上界。
第二行有个正整数
输出描述:
一个整数,代表最后的取法数量。
示例1
输入
复制
5 2 4
1 4 2 2 1
输出
复制
6
说明
共有以下6种取法:
i=1,j=3,ai+aj=1+2=3i=1,j=3,a_i+a_j=1+2=3\i=1,j=3,ai+aj=1+2=3
i=1,j=4,ai+aj=1+2=3i=1,j=4,a_i+a_j=1+2=3\i=1,j=4,ai+aj=1+2=3
i=1,j=5,ai+aj=1+1=2i=1,j=5,a_i+a_j=1+1=2\i=1,j=5,ai+aj=1+1=2
i=3,j=4,ai+aj=2+2=4i=3,j=4,a_i+a_j=2+2=4\i=3,j=4,ai+aj=2+2=4
i=3,j=5,ai+aj=2+1=3i=3,j=5,a_i+a_j=2+1=3\i=3,j=5,ai+aj=2+1=3
i=4,j=5,ai+aj=2+1=3i=4,j=5,a_i+a_j=2+1=3\i=4,j=5,ai+aj=2+1=3
备注:
对于10%的数据,
对于30%的数据,
对于50%的数据,
对于100%的数据,
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
typedef long long ll;
int a[int(1e5 + 10)];
int n, x, y;
int find_l(int l, int r, int target) {
int ans = 0;
while(l <= r) {
int mid = (l + r) >> 1;
if(a[mid] >= target) {
ans = mid;
r = mid - 1;
}
else
l = mid + 1;
}
return ans;
}
int find_r(int l, int r, int target) {
int ans = 0;
while(l <= r) {
int mid = (l + r) >> 1;
if(a[mid] <= target) {
ans = mid;
l = mid + 1;
}
else
r = mid - 1;
}
return ans;
}
int main() {
cin >> n >> x >> y;
for(int i = 1; i <= n; i++)
cin >> a[i];
ll ans = 0;
sort(a + 1, a + 1 + n);
for(int i = 1; i <= n; i++) {
int l = find_l(i + 1, n, x - a[i]);
int r = find_r(i + 1, n, y - a[i]);
if(l == 0 || r == 0) continue;
ans += r - l + 1;
}
cout << ans << endl;
return 0;
}
给定一个数组和一个数值范围,利用二分搜索算法找出满足条件的两个数之和的取法数量。例如,对于数组 [1, 4, 2, 2, 1] 和范围 [2, 4],存在6种不同的取法。"
107304558,9822986,R语言数据框操作指南,"['R语言', '数据结构', '数据处理']

3132

被折叠的 条评论
为什么被折叠?



