1267.越挫越勇
Time Limit: 1000 MS Memory Limit: 32768 KB
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≤10^5,0≤k<10^9)
之后第二行输入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
没错,又是一道读错了题的衍生物= =懒得出英文题了,干脆直接中文出题,写博客还省的解释题意了→_→
在处理的时候先进行一下排序,然后从后往前找,如果找的前一个数可以赢后一个数,就继续往后找,如果前一个数无法赢,就停止,因为现在可以肯定前面的那些数都是无法赢的了。然后再处理留下来的这些数,用最大的减去最小的那个数,如果他们的差距不大于k,说明最小的那个数肯定是最后的胜者,输出这个最小的数。否则无法确定哪个人获得冠军,就从小到大将这些留下的数都输出出来,即可得到答案。
下面AC代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int a[100005];
int main()
{
int T;
int n,k;
int i,j;
int ans;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&k);
for(i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
sort(a,a+n);
ans=1;
for(i=n-1;i>=1;i--)
{
if(a[i]-a[i-1]<=k)
{
ans++;
}
else
{
if(a[n-1]-a[i]<=k)
{
ans=0;
cout<<a[i]<<endl;
}
break;
}
}
if(ans&&a[n-1]-a[i]<=k)
{
ans=0;
cout<<a[i]<<endl;
}
if(ans)
{
for(;i<n-1;i++)
{
cout<<a[i]<<" ";
}
cout<<a[i]<<endl;
}
//cout<<ans<<endl;
}
return 0;
}