HDU1011 Rikka with Competition 题解报告

题目传送门

【题目大意】

有$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$。所以我们只需要把每个选手的实力排序后从大到小扫描,如果当前条件不满足则退出循环,即后面实力更小的选手没有机会获胜了,细节见代码。

【代码实现】

HDU1011 Rikka with Competition 题解报告
 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 }
代码戳这里
上一篇:Ocean Color Level 2 数据中 32 bits l2_flags各位的意义


下一篇:Redis去重方法