题意:求数组中两个不同元素使得两元素和%p最大。
分析:
1、序列中的数可能超过P,将所有数读入后进行模P操作。
2、将取模后的所有数从小到大排序,现在所有数都是小于P且排好序的。
3、假设任意选了两个数X和Y,则0≤X+Y≤2P-2。若X+Y<P,则答案就是X+Y,若X+Y≥P,答案是X+Y-P。 从小到大枚举第一个数,另一个匹配的数显然是从大到小的,可以用POS记录当前另一个匹配的数的位置,每次枚举时POS递减至符合条件。可以做到O(n)的时间复杂度。这题还可以使用二分等方法。
#include<iostream> #include<algorithm> using namespace std; __int64 a[100005]; int main() { int n,i,pos; __int64 p,max; while(scanf("%d%I64d",&n,&p)==2) { for(i=0;i<n;i++) { scanf("%I64d",&a[i]); a[i]%=p; } sort(a,a+n); max=(a[n-1]+a[n-2])%p; //确保取到和大于p时的最大值,因为经过输入处理后两个数的和最大只能是2p-2。 pos=n-1; for(i=0;i<pos;i++) //从两端逼近 { max=max>(a[i]+a[pos])%p?max:(a[i]+a[pos])%p; if(a[i]+a[pos]>=p) { pos--; i--; } } printf("%I64d\n",max); } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/a809146548/article/details/46662101