1 条题解

  • 2
    @ 2024-3-8 15:01:51

    这道题,如果直接枚举的话,时间复杂度为O(n2)O(n^2)只能得70分。所以需要用两个数列的双指针进行优化。利用排序后的数组单调性进行求解:即当数组a的整数更大时,能够有更多的b[j]使得它们的和非负。 \\首先对数组a从小到大排序,对数组b从大到小排序。定义两个指针pa和pb初始时候都指向1。考虑a[pa]+b[pb]a[pa]+b[pb]的正负性。 \\情况一:a[pa]+b[pb]>=0a[pa]+b[pb]>=0。说明负数可能可以取的更小一些,所以pb++pb++ \\情况二:a[pa]+b[pb]<0a[pa]+b[pb]<0,说明此时a[pa]a[pa]对应符合要求的b只能是b[1]b[1]b[pb1]b[pb-1],即ans加上pb-1。要想再次让和为非负数,只能让正数取得更大,所以pa++pa++. \\最后结束循环时。如果pa<npa<n,那么a[pa]到a[n]这些数,加上任意一个b数组中的数,都是非负的。ans需要加上这部分剩余的情况。

    参考代码
    
    #include<bits/stdc++.h>
    using namespace std;
    const int N=100005;
    int a[N],b[N],n;
    long long ans=0;
    int main()
    {
    	cin>>n;
    	for(int i=1;i<=n;i++)
    		cin>>a[i];
    	for(int i=1;i<=n;i++)
    		cin>>b[i];
    	sort(a+1,a+n+1);
    	sort(b+1,b+n+1,greater<int>());
    	int pa=1,pb=1;
    	while(pa<=n&&pb<=n)
    	{
    		if(a[pa]+b[pb]>=0)
    			pb++;
    		else if(a[pa]+b[pb]<0)
    		{
    			ans+=pb-1;
    			pa++;	
    		}
    
    }
    if(pa<n);
    ans+=(long long)n*(n-pa+1); 
    cout<<ans;
    

    }

    </p>
    • 1

    信息

    ID
    689
    时间
    1000ms
    内存
    256MiB
    难度
    2
    标签
    (无)
    递交数
    64
    已通过
    40
    上传者