A - Cats and Fish(贪心+思维)

感受
不 是 特 别 难 , 但 是 细 节 要 处 理 好 , 不 然 码 代 码 就 可 能 有 b u g 。 不是特别难,但是细节要处理好,不然码代码就可能有bug。 bug
思路
首 先 意 识 到 如 果 鱼 的 数 量 很 充 足 , 那 么 x 时 刻 每 只 猫 吃 完 整 鱼 的 数 量 以 及 未 吃 完 的 鱼 数 量 可 以 O ( 1 ) 求 出 首先意识到如果鱼的数量很充足,那么x时刻每只猫吃完整鱼\\的数量以及未吃完的鱼数量可以O(1)求出 xO(1)
即 f [ i ] = x / c [ i ] , r f [ i ] = x % c [ i ] 其 中 f [ i ] 表 示 第 i 只 猫 吃 完 整 鱼 的 数 量 , r f [ i ] 表 示 第 i 只 猫 未 吃 完 鱼 的 数 量 即f[i]=x/c[i],rf[i]=x\%c[i]\\其中f[i]表示第i只猫吃完整鱼的数量,rf[i]表示第i只猫未吃完鱼的\\数量 f[i]=x/c[i],rf[i]=x%c[i]f[i]i,rf[i]i
回 到 这 个 问 题 上 如 果 x ′ 时 刻 计 算 出 的 ∑ i = 1 n ( f [ i ] + r f [ i ] ) ≤ m ; 如 果 x ′ + 1 时 刻 ∑ i = 1 n ( f [ i ] + r f [ i ] ) > m 回到这个问题上\\如果x'时刻计算出的\sum_{i=1}^{n}(f[i]+rf[i])≤m;\\如果x'+1时刻\sum_{i=1}^{n}(f[i]+rf[i])>m xi=1n(f[i]+rf[i])mx+1i=1n(f[i]+rf[i])>m
而 且 c [ i ] ≥ 1 也 就 说 从 x ′ 时 刻 到 x ′ + 1 时 刻 每 一 只 猫 最 多 还 能 吃 一 条 鱼 而且c[i]≥1也就说从x'时刻到x'+1时刻每一只猫最多还能吃\\一条鱼 c[i]1xx+1
这 个 性 质 特 别 重 要 ! 可 能 有 人 会 问 , 会 不 会 有 猫 会 吃 2 条 以 上 的 鱼 呢 ? 显 然 不 可 能 , 因 为 时 间 对 于 每 一 条 猫 都 是 独 立 的 , 如 果 有 猫 可 以 吃 2 条 以 上 的 鱼 , 也 就 是 说 x ′ + 1 时 刻 ∑ i = 1 n ( f [ i ] + r f [ i ] ) ≤ m , 与 前 面 矛 盾 。 这个性质特别重要!可能有人会问,会不会有猫会吃2条以上的\\鱼呢?显然不可能,因为时间对于每一条猫都是独立的,如果\\有猫可以吃2条以上的鱼,也就是说x'+1时刻\sum_{i=1}^{n}(f[i]+rf[i])≤m,与前面矛盾。 22x+1i=1n(f[i]+rf[i])m
因 此 从 x ′ 时 刻 到 x ′ + 1 时 刻 每 一 只 猫 最 多 还 能 吃 一 条 鱼 因此从x'时刻到x'+1时刻每一只猫最多还能吃一条鱼 xx+1
有 了 上 述 性 质 , 我 们 就 可 以 枚 举 多 的 1 时 刻 可 以 让 哪 些 猫 吃 鱼 ? 有了上述性质,我们就可以枚举多的1时刻可以让哪些猫吃鱼? 1
由 于 只 是 多 1 时 刻 而 且 c [ i ] ≥ 1 , 也 就 是 说 只 有 在 x ′ 时 刻 刚 好 吃 完 的 才 有 可 能 吃 鱼 。 由于只是多1时刻而且c[i]≥1,也就是说只有在x'时刻刚好吃完\\的才有可能吃鱼。 1c[i]1x
如 果 有 多 个 猫 同 时 吃 完 呢 ? 题 目 描 述 中 写 过 , 吃 得 快 优 先 选 择 ! 如果有多个猫同时吃完呢?题目描述中写过,吃得快优先选择!
因 此 , 我 们 把 c [ i ] 排 序 即 可 。 因此,我们把c[i]排序即可。 c[i]
通 过 上 述 论 述 , 我 们 可 以 解 决 吃 新 鱼 的 过 程 。 那 剩 下 有 些 鱼 还 没 吃 完 怎 么 办 呢 ? 通过上述论述,我们可以解决吃新鱼的过程。那剩下有些鱼\\还没吃完怎么办呢?
剩 下 x − x ′ 时 间 就 是 来 处 理 这 些 剩 余 的 , 如 果 这 个 时 间 刚 好 让 它 吃 完 , r f [ i ] − − , f [ i ] + + 剩下x-x'时间就是来处理这些剩余的,如果这个时间刚好让它吃完,\\rf[i]--,f[i]++ xxrf[i],f[i]++

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
int f, rf;///f表示吃完整鱼数量  rf表示吃剩下的鱼数量
int n, m, x, now;///m条鱼  n条猫
int c[200];
int res[200];///吃完剩余所需要的时间
bool check(int x){
	f = rf = 0;
	for(int i = 1; i <= n; i++){
		f = f + x / c[i];
		if(x % c[i]){
			rf++;
			res[i] = c[i] - x % c[i];
		}
		else{
			res[i] = 0;
		}
	}
	if(f + rf > m) return false;
	return true;
}
int main(){
	while(scanf("%d%d%d", &m, &n, &x) != EOF){
		for(int i = 1; i <= n; i++){
			scanf("%d", &c[i]);
		}
		sort(c + 1, c + n + 1);
		for(now = x; ~now; now--){
			if(check(now)){
				break;
			}
		}
		if(now != x){
			for(int i = 1; i <= n; i++){
				if(!res[i]){
					if(f + rf == m) break;
					res[i] = c[i]; rf++;
				}
			}
			for(int i = 1; i <= n; i++){
				if(res[i] <= x - now && res[i]){
					rf--; f++;
				}
			}
		}
		printf("%d %d\n", m - f - rf, rf);
	}
	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值