SDNU 1267.越挫越勇
Time Limit: 1000 MS Memory Limit: 32768 KB
Total Submission(s): 13 Accepted Submission(s): 5
Description
在比赛的时候,实力是决定胜负的关键,一般而言,实力越高的人能够得到胜利。但是,如果双方实力很接近,反而会激发弱者的能力,使他心中有股拼劲想要超过对方,往往是弱的一方赢。(当然,如果实力差距太大弱的一方再努力也是赢不了的。)
现在,马上要开始一场比赛,我们假设有运动员a和运动员b(a的实力高于b),如果他们两个人的实力差距是小于等于k的话,那么我们可以认为激发了b的斗志,最后b获得胜利。但如果实力差距大于k,说明实力差距太大难以追上,最后还是a获得胜利。
而这场比赛的对手是随机对阵的,已知有n个运动员,每次比赛从中随机挑出两个人比赛,输的人直接淘汰,这样循环下去打n-1场比赛之后,最后没被淘汰的人就是比赛的最后冠军。
lmh现在想打赌猜出比赛冠军,所以他需要知道最后有机会获胜的人的实力分别是多少然后再从中猜,但他不知道都有谁有可能成为冠军,你能帮帮他吗?
Input
第一行输入一个T,代表总共有T组测试数据。(1≤T≤100)
对于每组样例,第一行包含两个数n,k,分别表示有n个队员,以及他们实力差距的界限k。(1≤n≤105,0≤k<109)
之后第二行输入n个运动员的能力ai,不存在两个运动员的实力一样。(1≤ai≤10^9且a为整数).
Output
输出所有可能夺冠的人的实力于一行中,两个实力中间有一个空格。输出时输出字典序最小的答案。
Sample Input
2
5 3
1 5 9 6 3
5 2
1 5 9 6 3
Sample Output
1 3 5 6 9
9
典型的贪心算法,看起来很简单,但是有俩坑点:
1)如果在最后求出实力最差的选手和实力最强的选手的差距小于等于k时,这个实力最差的选手是必胜的(很奇怪的情况,仔细想想)。
2)最后的数据肯定去卡tle了,不能用cin和cout。
附上Ac代码:
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n;
scanf("%d",&n);
while(n--)
{
int m;
int k;
scanf("%d%d",&m,&k);
int s[100005];
for(int i=0; i<m; i++)
scanf("%d",&s[i]);
sort(s,s+m);
int minn=s[m-1]-k;
int js=1;
for(int i=m-2; i>=0; i--)
{
if(s[i]>=minn)
{
js++;
minn=s[i]-k;
}
else
break;
}
if(s[m-1]-s[m-js]<=k)
printf("%d\n",s[m-js]);
else
{
for(int i=m-js; i<m-1; i++)
printf("%d ",s[i]);
printf("%d\n",s[m-1]);
}
}
return 0;
}