题目链接:
hdu:http://acm.hdu.edu.cn/showproblem.php?pid=5265
bc(中文):http://bestcoder.hdu.edu.cn/contests/contest_chineseproblem.php?cid=599&pid=1002
题意:
从n个数中取两个数A,B,使得(A+B)%p最大。
题解:
首先对所有的数先取一次模,那么则有0<=a[i]+a[j]<=2*p-2(i!=j),对于a[i]+a[j]>=p的,只要使a[i],a[j]都最大即可求出最大的(a[i]+a[j])%p,因为a[i]+a[j]不可能超过2*p了。而对于a[i]+a[j]<p的那些,我们固定a[i],二分去找j,使得a[i]+a[j]<p且j尽可能大即可。
代码:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 typedef long long LL; 7 8 const int maxn=1e5+10; 9 10 int n,p; 11 LL a[maxn]; 12 13 int main(){ 14 while(scanf("%d%d",&n,&p)==2&&n){ 15 for(int i=0;i<n;i++){ 16 scanf("%lld",a+i); 17 a[i]%=p; 18 } 19 sort(a,a+n); 20 LL ans=(a[n-1]+a[n-2])%p; 21 for(int i=0;i<n-1;i++){ 22 LL tmp=a[i]; 23 int lef=i+1,rig=n; 24 while(lef<rig){ 25 int mid=lef+(rig-lef)/2; 26 if(tmp+a[mid]<p){ 27 if(tmp+a[mid]>ans) ans=tmp+a[mid]; 28 lef=mid+1; 29 }else{ 30 rig=mid; 31 } 32 } 33 } 34 printf("%lld ",ans); 35 } 36 return 0; 37 } 38 /* 39 4 5 40 1 2 3 4 41 */