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;
}