题目传送门
【题目大意】
有$n$个选手,每个选手有一个实力值$a_i$,如果两个选手$i,j$满足$|a_i-a_j|>k$,那么实力值大的选手获胜,否则两个选手都有可能获胜。每次从当前剩下的选手中任意选取两个比赛,求最多有多少个选手有机会获胜。
【思路分析】
对于实里第$i$大的选手,如果他有可能获胜,那么当且仅当实力第1大的选手输给实力第2大的,实力第2大的输给实力第3大的,依次类推,直到第$i$大,即要满足按照实力从大到小排序后,对于每一个$j\in[1,i-1]$,都要满足$a_j-a_{j+1}\le k$。所以我们只需要把每个选手的实力排序后从大到小扫描,如果当前条件不满足则退出循环,即后面实力更小的选手没有机会获胜了,细节见代码。
【代码实现】
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 #define g() getchar() 7 #define rg register 8 #define go(i,a,b) for(rg int i=a;i<=b;i++) 9 #define back(i,a,b) for(rg int i=a;i>=b;i--) 10 #define db double 11 #define ll long long 12 #define il inline 13 #define pf printf 14 using namespace std; 15 int fr(){ 16 int w=0,q=1; 17 char ch=g(); 18 while(ch<'0'||ch>'9'){ 19 if(ch=='-') q=-1; 20 ch=g(); 21 } 22 while(ch>='0'&&ch<='9') w=(w<<1)+(w<<3)+ch-'0',ch=g(); 23 return w*q; 24 } 25 const int N=1e5+2; 26 int T,n,k,a[N]; 27 int main(){ 28 //freopen("","r",stdin); 29 //freopen("","w",stdout); 30 T=fr(); 31 while(T--){ 32 n=fr();k=fr(); 33 go(i,1,n) a[i]=fr(); 34 sort(a+1,a+1+n); 35 rg int ans=1;//初始值为1是因为实力最大的选手一定有可能获胜 36 back(i,n,2){ 37 if(a[i]-a[i-1]>k) break; 38 ans++;//这是实力第i-1大的选手可能获胜 39 } 40 pf("%d\n",ans); 41 } 42 return 0; 43 }代码戳这里