A. 大家一起点外卖 2014新生暑假个人排位赛04
时间限制 2000 ms
内存限制 65536 KB
题目描述
大家都回了本部,本部生活虽然没有宏福天(mo)堂(gui)般的生活,但是却有很多外卖,今天有一家饭店新开张,凡是两个人的餐点费用之和刚好为m可以免运费,在今天一起点外卖且免运送费的两个人,各自点的外卖价格差值最小的有大惊喜。在机房的n个同学今天打算一起点外卖,但是每个人都只想要点某一个价格x的餐点,请你帮忙规划一下大家应当如何组合,并给出最有可能获得今天大惊喜的价格组合。
输入格式
第一行输入样例数 T 对于每一个样例 第一行输入整数 n(0≤ n≤500000) ,整数 m(0≤m≤2000000) 接下来的 n 行,每行输入一个整数x代表每一个人想点的餐点的价格 0≤x≤1000000
输出格式
如果能够找到最有可能获得今天大惊喜的价格组合,则输出两个人所点的餐点的价格,小的价格在前。
如果所有人都没办法免运送费,则输出“Sad”
输入样例
2
2 3
1
3
4 3
1
2
3
4
输出样例
Sad
1 2
思路:就直接从差值为0开始朝两头扩展,注意差值为0时不要重复累加,故k1==k2与k1!=k2来讨论向两边枚举。复杂度O(n)即可以过。
代码:
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#define maxn 2000005
//#define LOCAL
using namespace std;
int n,m;
int num[maxn];
int main()
{
#ifdef LOCAL
freopen("input.txt","r",stdin);
#endif // LOCAL
int T;
scanf("%d",&T);
while(T--)
{
memset(num,0,sizeof(num));
scanf("%d%d",&n,&m);
int temp;
for(int i=1;i<=n;i++)
{
scanf("%d",&temp);
num[temp]++;
}
int k1=m/2;int k2=m-m/2;bool flag=0;
while(k1>=1)
{
if(k1!=k2)
{
if(num[k1]&&num[k2]){printf("%d %d\n",k1,k2);flag=1;break;}
else {k1--;k2++;}
}
else if(k1==k2)
{
if(num[k1]>=2){printf("%d %d\n",k1,k2);flag=1;break;}
else {k1--;k2++;}
}
}
if(flag)continue;
else printf("Sad\n");
}
return 0;
}