您的位置:首页 > 其它

BestCoder Round #43 第二题 pog loves szh II

2015-06-07 20:57 288 查看

pog loves szh II

  Accepts: 219  Submissions: 834 Time Limit: 4000/2000 MS (Java/Others)  Memory Limit: 65536/65536 K (Java/Others)问题描述
pog在与szh玩游戏,首先pog找到了一个包含n个数的序列,然后他在这n个数中挑出了一个数A,szh出于对pog的爱,在余下的n−1个数中也挑了一个数B,那么szh与pog的恩爱值为(A+B)对p取模后的余数,pog与szh当然想让恩爱值越高越好,并且他们想知道最高的恩爱值是多少。
输入描述
若干组数据(不超过5组n≥1000)。
每组数据第一行两个整数n(2≤n≤100000),p(1≤p≤231−1)。
接下来一行n个整数ai(0≤ai≤231−1)。
输出描述
对于每组的每个询问,输出一行,表示pog与szh的最大恩爱值。
输入样例
4 4
1 2 3 0
4 4
0 0 2 2
输出样例
3
2
由于序列中的数可能超过P,所以将所有的数读入后进行取模操作。之后将取模后的所有数从小到大排序。题目要求我们求不同位置的两个数的和在取模意义下的最大值,而现在所有数都是小于P且排好序的。因此设我任意选了两个数是X和Y,显然0≤X+Y≤2P−2。若X+Y<P,则这次选数的答案就是X+Y,若X+Y\gepP,则答案是X+Y−P。那么我们可以这样做:将其中最大的两个数字相加取模,设为一个可能的答案记录在ANS中。这个答案是第二种情况的最大值。再对排序好的序列进行枚举,对每个枚举到的数,找出最大的数,使这个数与枚举到的数相加后的和最大且小于P,将之记为可能的答案并于之前找到的最大值ANS进行比较。这个答案是第一种情况中的可能的最大值。而普通的枚举是要超时的,但是我们发现如果从小到大枚举第一个数,那么另一个匹配的数显然是从大到小的,因此可以用一个NOW记录当前另一个匹配的数的位置,每次枚举时NOW递减至符合条件。可以做到O(n)的时间复杂度。综上所述,时间复杂度为快速排序的O(nlogn),空间复杂度为O(n)。注意一些特殊情况如同一个位置不能多次选。#include <iostream>#include <cstdio>#include <cstring>#include<algorithm>using namespace std;int a[100010];int main(){int n,p;while(cin>>n>>p){for(int i = 1;i<=n;i++){scanf("%d",&a[i]);a[i]%=p;}sort(a+1,a+n+1);int ans = (a+a[n-1])%p;int last = n;for(int i = 1; i<=n;i++){while(last && a[last]+a[i]>= p) last--;if(last) ans = max(ans,a[last]+ a[i]);}cout<<ans<<endl;}return 0;}
                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: