bestcoder#43 1002 在数组中找两个数的和取模的最大值 二分

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,n1000).

For each case:

The following line contains two integers,n(2n100000)p(1p2311)

The following line contains n integers ai(0ai2311)

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;
}
View Code

 

posted @ 2015-06-08 18:19  __560  阅读(671)  评论(0编辑  收藏  举报