这道题首先呢让我没有办法做到的是,(如何两两选择不重复:隆重推出尺取法)
详见大佬博客:
大佬博客传送门
那么我们这道题就是暴力枚举所有的可能结果,最后分析哪一个是最大的,对本题数据排序以后使用尺取法就十分巧妙的避开了两两不重复:
只有符合它a[l]+a[r]==i&&l<r
我才可以继续进行,
如果是a[l]+a[r]<i&&l<r
就说明这个数据太小应该让小数据往右移动(因为我们r右边的数据都已经试过了所以不用考虑r右边的),对另外一种情况同理,结束循环的条件当然是左右区间的端点值重合就结束取最大值。
#include<iostream>
#include<algorithm>
using namespace std;
int a[21021020];
int main(){
int T;
cin>>T;
while(T--){
int n;
cin>>n;
int minn=0x3f3f3f3f;
int maxx=-0x3f3f3f3f;
for(int i=1;i<=n;i++) {
cin>>a[i];
minn=min(minn,a[i]);
maxx=max(maxx,a[i]);
}
sort(a+1,a+1+n);
int ans=-1;
for(int i=minn*2;i<=maxx*2;i++){
int l=1,r=n;
int num=0;
while(1){
while(a[l]+a[r]==i&&l<r){
l++,r--;
num++;
}
/*上面这是符合情况的例子,因为用过了所以l++,r--*/
while(a[l]+a[r]<i&&l<r){
l++;
}
while(a[l]+a[r]>i&&l<r){
r--;
}
/*上面这是不符合情况的例子因此没有num++,而且对排过序的数组遥相对应的减少*/
if(l>=r){
ans=max(num,ans);
break;
}
}
}
cout<<ans<<endl;
}
return 0;
}