很明显这道题给了你两种可能的选择情况,一种是不贪心,看看一开始就不如p的两堆,一种是加在一起后被余p后仍然是最大的情况
首先,这道题里不可能出现比p大的情况,我们先把自己一个本身就大于p的全部在输入时就取MOD一次,然后对于第一种情况,很明显两个被MOD过的数字加在一起肯定是小于2 * p的,所以说只用无脑拿到最大之后MOD就行了。对于第二种情况,不断找并判断加起来最小的,我们可以使用双指针加速,如果大了就r减小,如果小了就l增大,对于每一种1合规情况检查一下就行了,排序后的数组的单调性让双指针肯定能不重不漏(双指针与贪心在这一点上确实很像哈)
#include <bits/stdc++.h>
using namespace std;
#define int long long
signed main()
{
int T;
cin>>T;
while(T--)
{
int n,p;
cin>>n>>p;
vector<int> thenum(n);
for(int r = 0;r < n;r++)
{
cin>>thenum[r];
thenum[r] = thenum[r] % p;
}
sort(thenum.begin(),thenum.end());
int ans = (thenum[n - 1] + thenum[n - 2]) % p;
int l = 0;
int r = n - 1;
while(l < r)
{
while(thenum[l] + thenum[r] >= p)
{
r--;
}
if(l < r)
{
ans = max(ans,thenum[l] + thenum[r]);
l++;
}
}
cout<<ans<<'\n';
}
return 0;
}

京公网安备 11010502036488号