题意:
这道题就是有两个数组,
a数组代表老师的值,b数组代表学生的值
要求是
老师的两个值要比学生的两个值要大,这就是good
输出一共有几个good
比赛思路:
我比赛的时候写的太慢了,但是最后还是有思路的
就是用一个c数组 ,存a[i]-b[i]的值 ;这样就只要数这个c数组里有几对组合是加起来是大于0就好了。
然后我想的是先sort然后while(l<r),就是左右指针卡;
如果a[l]+a[r]<=0,那就l++,如果>0,那就有r-l个 good。
如果这次满足了,r就–,缩小范围。
大致意思就是这样,
cin >> n;
vector<int> a(n), b(n);
for (int i=0;i<n;i++) cin >> a[i];
for (int i=0;i<n;i++) cin >> b[i];
vector<int> c(n);
for (int i = 0; i < n; ++i) {
c[i] = a[i] - b[i];
}
sort(c.begin(), c.end());
long long ans = 0;
int l=0,r=n-1;
while(l<r){
if(c[l]+c[r]>0){
ans+=r-l;
r--;
}else{
l++;
}
}
cout << ans << endl;
哈哈哈哈哈哈 棒
美滋滋
然后放上标程的代码:
cin >> n;
vector<int> a(n), b(n);
for (int i=0;i<n;i++) cin >> a[i];
for (int i=0;i<n;i++) cin >> b[i];
vector<int> c(n);
for (int i = 0; i < n; ++i) {
c[i] = a[i] - b[i];
}
sort(c.begin(), c.end());
long long ans = 0;
int l=0,r=n-1;
for (int i = 0; i < n; ++i) {
if (c[i] <= 0) continue;
int pos = lower_bound(c.begin(), c.end(), -c[i] + 1) - c.begin();
ans += i - pos;
}
cout << ans << endl;
前面的也都一样,主要就是用了lower_bound比较妙
他的思路就是遍历一遍数组;
然后每次看这个数组里>=(-c[i]+1)的第一个坐标在哪里,从这个数开始到后面,这几个数肯定和 当前的c[i]加起来大于0;
然后每次加上坐标的差值就好
这两种的复杂度一样都是O(nlogn)