题目链接:16.聪明的小羊肖恩 - 蓝桥云课
1.初始代码:
#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,l,r;
int a[200010];
signed main()
{
cin>>n>>l>>r;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
sort(a+1,a+n+1);
int sum1=0;
for(int i=1;i<=n;i++)
{
int sum=0;
for(int j=i+1;j<=n;j++) //完整一次循环是一个子区间
{
sum=a[i]+a[j];
if(sum>=l && sum<=r)
{
sum1++;
}
}
}
cout<<sum1<<endl;
return 0;
}
大约能够过75%,只是对遍历进行了优化,其实没有真正利用到sort排序
2.方法一:
排序后,利用二分优化时间复杂度,首先推导出:l-a[i]<=a[j]<=r-a[j] ,然后查找所有满足条件的a[j],累加求和
#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,l,r;
int a[200010];
signed main()
{
cin>>n>>l>>r;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
sort(a+1,a+n+1);
//l-a[i]<=a[j]<=r-a[j]
int sum=0;
for(int i=1;i<=n;i++)
{
int l1=l-a[i],r1=r-a[i];
sum+=upper_bound(a+i+1,a+1+n,r1)-lower_bound(a+i+1,a+1+n,l1);
}
cout<<sum<<endl;
return 0;
}
3.方法二:
排序后,使用双指针优化时间复杂度,双指针遍历,累加求和1-L和1-R满足条件的和
#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,l,r;
int a[200010];
int sum(int x)
{
int l1=1,r1=n,ans=0;
while(l1<r1)
{
if(a[l1]+a[r1]<=x)
{
ans+=r1-l1;
l1++;
}
else
{
r1--;
}
}
return ans;
}
signed main()
{
cin>>n>>l>>r;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
sort(a+1,a+n+1);
//容斥原理:sum[l-1...r]=sum[r]-sum[l-1]
cout<<sum(r)-sum(l-1)<<endl;
return 0;
}