hdu-5265pog loves szh II

来源:互联网 发布:安卓更改mac地址 编辑:程序博客网 时间:2024/05/22 03:23

pog loves szh II

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 1357    Accepted Submission(s): 391


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 41 2 3 04 40 0 2 2
 

Sample Output
32
 


题意:给你N个数和一个数P,让你找出两个数A和B,使得(A+B)%P的值最大,并且输出这个最大值
思路:拿到题,首先就是将读入的数先取模模P,然后排序。然后我就得到了N个0到P-1的数,从这些数中找出两个不同的数,他们的和范围是0到2P-2。
那么分两种情况考虑:考虑和大于等于P的情况,显然若两个数相加大于P并且模完P还是最大,那么肯定取最大的两个数(若两个数相加小于P,那么只是退化到和小于P的情况,造成多判的情况,并不会影响最后答案的正确)
然后考虑和小于P的情况:这里有两种做法。
1是遍历所有数(其实并不需要所有,这里还可以优化),将P-你正在遍历的数,然后在数组二分查找小于这个数的最大数,(这里要保证不能同时取同一个数两次)更新两个数加起来的最大值,即为答案。
2是设双指针,一头一尾,如果当前和大于等于P,尾指针-1;如果当前和小于P,头指针+1;循环条件是头指针小于尾指针。在过程中不断更新最大值。
综合考虑两种做法:二分实现起来麻烦,而且需要验证是否为同一个数,且复杂度为O(nlogn)
                                双指针比较好写,且复杂度为O(n);
虽然总的复杂度还是排序的nlogn,但还是推荐第二种写法
#include <cstdio>#include <algorithm>#define maxn 100000+5using namespace std;typedef long long ll;ll a[maxn];void read(ll& x){    x=0;    int flag=0;    char c=getchar();    if(c=='-')flag=1;    while(c<'0'||c>'9')    {        if(c=='0')flag=1;        c=getchar();    }    while(c>='0'&&c<='9')    {        x=x*10+c-'0';        c=getchar();    }    if(flag)x=-x;}int main(){    ll n,p;    while(~scanf("%lld %lld",&n,&p))    {        for(int i=0;i<n;i++)        {            read(a[i]);            a[i]%=p;        }        sort(a,a+n);        ll ans=(a[n-1]+a[n-2])%p;        int l=0,r=n-1;        while(l<r)        {            ans=max(ans,(a[l]+a[r])%p);            if(a[l]+a[r]<p)l++;            else r--;        }        printf("%lld\n",ans);    }    return 0;}


0 0
原创粉丝点击