这个题花费了我两天的时间来解决,最终找到了两个比较简单的方法
首先这个题不难看出是寻找a[i]+a[j]<0的情况,我第一开始直接用两个for循环遍历通过不了,应该是复杂度太大了
第一个方法
#include<algorithm> #include<iostream> #include<functional> typedef long long ll; using namespace std; const long long maxn = 2e5 + 10;//记住这里的定义前面一定要加const,不然maxn是变量,定义数组时会发生错误 int a[maxn], b[maxn], c[maxn];//这里数组长度太大,不能在主函数中定义 int main() { int n; cin >> n; for (int i = 1; i <= n; i++) { cin >> a[i]; } for (int i = 1; i <= n; i++) { cin >> b[i]; c[i] = a[i] - b[i]; } sort(a + 1, a + n + 1, greater<int>());//降序排列 int j = n; long long ans = 0; for (int i = 1; i <= n; i++) { while (c[i] + c[j] <= 0 && i < j) { j--; } if (i >= j) //避免交叉重复 break; ans += 1ll*j - i;//实现类型转化 } cout << ans << endl; }
第二个方法是用一个upper_bround函数,这个函数是利用二分法寻找,所以复杂度比较低
#include<iostream> #include<algorithm> using namespace std; typedef long long ll; const long long maxn=2e5+10; int a[maxn],b[maxn],c[maxn]; int main(){ int n; cin>>n; for(int i=1;i<=n;i++){ cin>>a[i]; } for(int i=1;i<=n;i++){ cin>>b[i]; c[i]=a[i]-b[i]; } sort(c+1,c+n+1,greater<int>());//降序排列 ll ans=0; for(int i=1;i<n;i++){ int j=upper_bound(c+i+1,c+n+1,-c[i])-c; ans+=(n-j+1)*1ll; } cout<<ans<<endl; }