饿饿 饭饭

题目:

 题目链接 :饿饿 饭饭 - 题目 - Daimayuan Online Judge


思路:

因为存在每对于所有的同学进行

打一次的饭的话

那么对于剩下的同学

他们仍然按照的原来的顺序排列(假如他们进行这一次打饭,他们都还需要打饭)

那么我们就只需要求

刚好要进行多少的轮次后

(刚好进行下一轮就大于k次打饭的次数)

再对剩余的同学进行模拟

但我们要注意有可能进行一定的轮次后

有的同学早已经吃完的然后离开

所有对于该情况需要特殊的讨论

对于剩下的还剩余吃饭次数的同学

我们将其分为两部分

第一部分是需要阿姨打饭并判断他们是否会离开的部分

第二部分是阿姨打饭已经打完了k次但仍然还在排队的部分


代码详解:

#include<stdio.h>
#include<iostream>
using namespace std;
typedef long long ll;
ll a[(ll)1e5 + 3],c[(ll)1e5+3];
ll n, k, sum = 0;
ll sumrice(ll t)
{
	ll ans = 0;
	for (int i = 1; i <= n; i++)
		ans += min(a[i],t);//如果进行的人要吃的饭的次数小于t那么只需要吃
	return ans;
}

int main()
{
	cin >> n >> k;
	for (int i = 1; i <= n; i++)
	{
		scanf("%lld", &a[i]),
		sum += a[i];
	}
	if (k>sum) printf("-1");//当阿姨要打的次数大于所有人需要打的次数
	else
	{
		int l = 0, r = 1e9;
		while (l+1 < r)//二分找到刚好小于阿姨要打饭次数轮数
		{
			ll mid = (l + r) / 2;
			if (sumrice(mid) <= k)//当打饭的总次数小于k时使左边取中间值
				l = mid;
			else//右边取中间值
				r = mid;
		}
		int tsum = k - sumrice(l);//阿姨剩余要打饭的次数
		int t = 0;//记录经过l轮后还剩余的人总数
		for (int i = 1; i <= n; i++)
		{
			if (a[i] > l) c[++t] = i;//存剩下的人的编号
		}
		for (int i = tsum + 1; i <= t; i++)
			printf("%lld ",c[i]);//输出进行剩余tsum次后的人的编号
		for (int i = 1; i <= tsum; i++)
		{
			if (a[c[i]]!= l+1) printf("%lld ", c[i]);//如果该编号上的人要打的饭的次数刚好不等于1,那么
		}
	}
	return 0;
}

PS:不经一番寒彻骨,怎得梅花扑鼻香。

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CTGU-Yoghurt

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值