题目描述
小雪非常关注自行车比赛,尤其是环滨湖自行车赛。一年一度的环滨湖自行车赛,需要选手们连续比赛数日,最终按照累计得分决出冠军。今年一共有 N 位参赛选手。每一天的比赛总会决出当日的排名,第一名的选手会获得 N 点得分,第二名会获得 N-1 点得分,第三名会获得 N-2 点得分,依次类推,最后一名会获得 1 点得分。保证没有选手会排名相同。
在之前的数日较量中, N 位选手已经分别累计了一些分数。现在即将开始的是最后一天的比赛。小雪希望知道有多少位选手还有可能获得最终的冠军,也就是说还有多少选手有可能通过最后一天的比赛获得累计总分第一名
输入输出格式
输入格式:
第一行输入一个整数 N,表示参赛选手总数,保证 3<=N<=300000。
之后 N 行,其中第 i 行输入一个整数 B[i]表示第 i 位选手已经获得的累计分数,满足0<=B[i]<=2000000。
输出格式:
输出只有一行,只输出一个整数,表示有多少位选手有可能获得最终的冠军。
输入输出样例
3 8 10 9
3
5 15 14 15 12 14
4
说明
对于 20%的数据, 3<=N<=600。
对于 50%的数据, 3<=N<=10000。
对于 100%的数据, 3<=N<=300000 且 0<=B[i]<=2000000。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
就是模拟题~
排了一个序,既可以求最大值,也可以减少循环次数~
这道题的正解思路应该是每一个运动员之前得分加上总人数n,如果大于 [ 其他人之前得分从小到大排序依次加上n-1~1 ] 这个分的最大值的话,ans++。
但是感觉实现起来好麻烦啊,根本不会耶,看神犇的程序,居然只需要和最大值+1比就可以了么?感觉不对啊……但是真的可以A……应该是数据太弱的原因。
(一道题测了9次,WA到飞起……)
对比时一定要加等号!不然会WA的!
#include<cstdio>
#include<algorithm>
using namespace std;
#define maxn 300000+6
int a[maxn],n,i,ans,k;
int findd(int u) //寻找离它最近的比它大的值
{
for(int i=u+1;i<=n;i++) if(a[i]>a[u]) return i;
return 0;
}
int main()
{
scanf("%d",&n);
for(i=1;i<=n;i++) scanf("%d",&a[i]);
sort(a+1,a+n+1);
for(int i=1;i<=n;i++)
if((a[i]+n)>=(a[n]+1))
if(k=findd(i)) //不是==
{
if((a[i]+n)>=(a[k]+n-k+1)) ans++;
}
else ans++;
printf("%d",ans);
return 0;
}