bestcoder#43 1002 在数组中找两个数的和取模的最大值 二分
pog loves szh II
Accepts: 97
Submissions: 834
Time Limit: 4000/2000 MS (Java/Others)
Memory Limit: 65536/65536 K (Java/Others)
Problem Description
Pog and Szh are playing games. There is a sequence with n numbers, Pog will choose a number A from the sequence. Szh will choose an another number named B from the rest in the sequence. Then the score will be (A+B) mod p. They hope to get the largest score. And what is the largest score?
Input
Several groups of data (no more than 5 groups,n≥1000).
For each case:
The following line contains two integers,n(2≤n≤100000),p(1≤p≤231−1)。
The following line contains n integers ai(0≤ai≤231−1)。
Output
For each case,output an integer means the largest score.
Sample Input
4 4 1 2 3 0 4 4 0 0 2 2
Sample Output
3 2
题意:给定数组a和整数p,在数组中找出两个数A,B,使(A+B)%p最大,输出最大值。
思路:对所有输入的数取模,排序,这时对任意两个在数组中的数A,B,有0<=A<=p-1,0<=B<=p-1,即0<=A+B<=2*p-2,因此(A+B)%p最大时有两种情况,即A+B<P,A+B小于但最接近P时最大,另一种是A+B>p,即A+B小于但最接近于2*p时最大。移项,固定A,查找小于p-A的第一个数以及小于2*p-A的第一个数,取最优的即可。
#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<vector> #include<stack> #include<queue> #include<set> #include<map> #include<string> #include<math.h> #include<cctype> using namespace std; typedef long long ll; const int maxn=1000100; const int INF=(1<<29); const double EPS=0.0000000001; const double Pi=acos(-1.0); ll n,p; ll a[maxn]; ll bin_search(int left,int right,ll key) { while(left<=right){ int mid=(left+right)/2; //cout<<left<<" "<<right<<" "<<mid<<endl; if(a[mid]>key) right=mid-1; else if((mid==n&&a[mid]<=key)||(a[mid+1]>key&&a[mid]<=key)) return a[mid]; else left=mid+1; } return -INF; } int main() { while(cin>>n>>p){ for(int i=1;i<=n;i++){ scanf("%I64d",&a[i]); a[i]%=p; } sort(a+1,a+n+1); ll ans=0; for(int i=1;i<=n-1;i++){ ll x=bin_search(i+1,n,p-a[i]); ll y=bin_search(i+1,n,2*p-a[i]); //cout<<"i+1="<<i+1<<" p-a[i]="<<p-a[i]<<endl; //cout<<"x="<<x<<" y="<<y<<endl; ll t=max((x+a[i])%p,(y+a[i])%p); if(t>ans) ans=t; } cout<<ans<<endl; } return 0; }