Codeforces Beta Round #72 (Div. 2 Only)D. Doctor
题目链接: 传送门
Doctor
time limit per test:1 second memory limit per test:256 megabytes
Description
There are n animals in the queue to Dr. Dolittle. When an animal comes into the office, the doctor examines him, gives prescriptions, appoints tests and may appoint extra examination. Doc knows all the forest animals perfectly well and therefore knows exactly that the animal number i in the queue will have to visit his office exactly ai times. We will assume that an examination takes much more time than making tests and other extra procedures, and therefore we will assume that once an animal leaves the room, it immediately gets to the end of the queue to the doctor. Of course, if the animal has visited the doctor as many times as necessary, then it doesn't have to stand at the end of the queue and it immediately goes home.
Doctor plans to go home after receiving k animals, and therefore what the queue will look like at that moment is important for him. Since the doctor works long hours and she can't get distracted like that after all, she asked you to figure it out.
Input
The first line of input data contains two space-separated integers n and k (1 ≤ n ≤ 10^5, 0 ≤ k ≤ 10^14). In the second line are given space-separated integers a1, a2, ..., an (1 ≤ ai ≤ 10^9).
Please do not use the %lld specificator to read or write 64-bit numbers in C++. It is recommended to use cin, cout streams (you can also use the %I64d specificator).
Output
If the doctor will overall carry out less than k examinations, print a single number "-1" (without quotes). Otherwise, print the sequence of numbers — number of animals in the order in which they stand in the queue.
Note that this sequence may be empty. This case is present in pretests. You can just print nothing or print one "End of line"-character. Both will be accepted.
Sample Input
3 3
1 2 1
4 10
3 3 2 1
7 10
1 3 3 1 2 3 1
Sample Output
2
-1
6 2 3
解体思路:
题目大意:n只动物排队看病,每只动物需要看病的次数不一,每次医生只给一只动物看病,未满足看病次数的动物在给医生看完病后需要排队尾再次等待。问K次后剩下的动物的编号序列。
通过二分找出动物们完成K次看病时单个动物看病次数的最大值,然后剔除已经满足看病次数的动物,最后对于未剔除的输出编号。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std;
typedef __int64 LL;
const LL INF = 0x3f3f3f3f;
LL ans[100005];
LL N,K;
bool OK(LL x)
{
LL sum = 0;
for (int i = 0;i < N;i++)
{
sum += min(x,ans[i]);
}
return sum >= K;
}
int main()
{
while (~scanf("%I64d%I64d",&N,&K))
{
LL sum = 0;
vector<LL>itv;
vector<LL>::iterator it;
memset(ans,0,sizeof(ans));
for (int i = 0;i < N;i++)
{
scanf("%I64d",&ans[i]);
sum += ans[i];
}
if (K > sum)
{
printf("-1\n");
continue;
}
LL left = 0,right = INF;
while (left < right - 1)
{
LL mid = left + ((right-left) >> 1);
if (OK(mid))
{
right = mid;
}
else
{
left = mid;
}
}
LL val = left;
for (int i = 0;i < N;i++)
{
K -= min(ans[i],val);
ans[i] -= min(ans[i],val);
}
for (int i = 0;i < N;i++)
{
if (K && ans[i])
{
ans[i]--;
K--;
}
else if (!K && ans[i])
{
itv.push_back(i+1);
ans[i] = 0;
}
}
for (int i = 0;i < N;i++)
{
if (ans[i])
{
itv.push_back(i+1);
}
}
bool first = true;
for (it = itv.begin();it != itv.end();it++)
{
first?printf("%I64d",*it):printf(" %I64d",*it);
first = false;
}
printf("\n");
}
return 0;
}
┆ 凉 ┆ 暖 ┆ 降 ┆ 等 ┆ 幸 ┆ 我 ┆ 我 ┆ 里 ┆ 将 ┆ ┆ 可 ┆ 有 ┆ 谦 ┆ 戮 ┆ 那 ┆ ┆ 大 ┆ ┆ 始 ┆ 然 ┆
┆ 薄 ┆ 一 ┆ 临 ┆ 你 ┆ 的 ┆ 还 ┆ 没 ┆ ┆ 来 ┆ ┆ 是 ┆ 来 ┆ 逊 ┆ 没 ┆ 些 ┆ ┆ 雁 ┆ ┆ 终 ┆ 而 ┆
┆ ┆ 暖 ┆ ┆ 如 ┆ 地 ┆ 站 ┆ 有 ┆ ┆ 也 ┆ ┆ 我 ┆ ┆ 的 ┆ 有 ┆ 精 ┆ ┆ 也 ┆ ┆ 没 ┆ 你 ┆
┆ ┆ 这 ┆ ┆ 试 ┆ 方 ┆ 在 ┆ 逃 ┆ ┆ 会 ┆ ┆ 在 ┆ ┆ 清 ┆ 来 ┆ 准 ┆ ┆ 没 ┆ ┆ 有 ┆ 没 ┆
┆ ┆ 生 ┆ ┆ 探 ┆ ┆ 最 ┆ 避 ┆ ┆ 在 ┆ ┆ 这 ┆ ┆ 晨 ┆ ┆ 的 ┆ ┆ 有 ┆ ┆ 来 ┆ 有 ┆
┆ ┆ 之 ┆ ┆ 般 ┆ ┆ 不 ┆ ┆ ┆ 这 ┆ ┆ 里 ┆ ┆ 没 ┆ ┆ 杀 ┆ ┆ 来 ┆ ┆ ┆ 来 ┆