传送门
题意
现在有
N
N
N个题目,每个题目有一个初始票数,
M
M
M个评委,每个评委可以为
V
V
V个不同的题目投票,投票结束之后选择分数前
P
P
P个的题目加入到题目集中,询问某种投票之后使得加入到题目集的题目数最多;
题解
首先将原数组
(
a
[
i
]
)
(a[i])
(a[i])进行降序排序,那么答案一定是从第
P
P
P个位置开始算起。怎么算呢?记一个前缀数组
b
[
i
]
b[i]
b[i]表示从到达当前位置时,前
i
i
i个位置都投票数变成
a
[
P
]
a[P]
a[P]是花费的总票数。那么从P位置开始枚举,对于每一个票数可以变为
a
[
P
]
a[P]
a[P]的题目进行判断,如果不满足条件就结束。具体判断看代码咯~
AC Code
#include<cstdio>
#include<algorithm>
using namespace std
;
typedef long long ll
;
const int MAXN
= 1e5 + 50;
ll N
,M
,V
,P
;
ll a
[MAXN
],b
[MAXN
],sum
;
int main()
{
scanf("%lld%lld%lld%lld",&N
,&M
,&V
,&P
);
sum
= M
* V
;
for(int i
= 1;i
<= N
;i
++)scanf("%lld",&a
[i
]);
sort(a
+ 1,a
+ 1 + N
,greater
<ll
>());
ll ans
= P
;
sum
-= (P
- 1) * M
;
for(int i
= P
;i
<= N
;i
++)
{
if(a
[i
] + M
>= a
[P
])b
[i
] = b
[i
- 1] + a
[P
] - a
[i
];
else break;
}
for(ll i
= P
;i
<= N
;i
++)
{
if(a
[i
] + M
>= a
[P
])
{
ll dis
= sum
- b
[i
];
ll mx
= M
- (a
[P
] - a
[i
]);
dis
-= mx
* (i
- P
+ 1);
if(dis
<= (N
- i
) * M
)ans
= i
;
else break;
}
}
printf("%lld",ans
);
return 0;
}