HDU ACM 5265 pog loves szh II

题意:求数组中两个不同元素使得两元素和%p最大。

分析:

1、序列中的数可能超过P,将所有数读入后进行模P操作。

2、将取模后的所有数从小到大排序,现在所有数都是小于P且排好序的。

3、假设任意选了两个数X和Y,则0≤X+Y≤2P-2。若X+Y<P,则答案就是X+Y,若X+Y≥P,答案是X+Y-P。 从小到大枚举第一个数,另一个匹配的数显然是从大到小的,可以用POS记录当前另一个匹配的数的位置,每次枚举时POS递减至符合条件。可以做到O(n)的时间复杂度。这题还可以使用二分等方法。

#include<iostream>
#include<algorithm>
using namespace std;

__int64 a[100005];

int main()
{
	int n,i,pos;
	__int64 p,max;

	while(scanf("%d%I64d",&n,&p)==2)
	{
		for(i=0;i<n;i++)
		{
			scanf("%I64d",&a[i]);
			a[i]%=p;
		}
		sort(a,a+n);
		max=(a[n-1]+a[n-2])%p;           //确保取到和大于p时的最大值,因为经过输入处理后两个数的和最大只能是2p-2。
		pos=n-1;
		for(i=0;i<pos;i++)      //从两端逼近
		{
			max=max>(a[i]+a[pos])%p?max:(a[i]+a[pos])%p;
			if(a[i]+a[pos]>=p)
			{
				pos--;
				i--;
			}
		}
		printf("%I64d\n",max);
	}
	return 0;
}


你可能感兴趣的:(编程,C++,c,算法,ACM)