Water Level

题目链接: Water Level

大致题意

有一个饮水机, 里面有k升水, 每天早上你可以像里面添加y升水, 每天晚上饮水机会被喝掉x升水.

问: 是否能在t天内, 使得饮水机的容量一直处于[l, r].

解题思路

首先这个题先进性一下左边界化简, 只需要让 k和r 都减去l即可. 之后都只需要考虑水的容量是否会大于r即可

此问题我们可以分类讨论:

​ ①如果 x == y, 那么每天的加水和喝水量是相同的, 因此只需要判断第一天能否加水, 以及能否喝到水即可. 往后的天数都会进行循环.

​ ②如果x > y 说明供不应求, 我们应该尽可能多的往里面进行加水操作. 而每天消耗的水应该是**(x - y)升**. 那么能坚持的天数day = k / (x - y) .
​ 需要注意的是: 如果我们以这样方式计算出来的day, 实际上是把加水和喝水同步进行了, 而题目中其实是先加再喝, 由于 x > y, 因此有加水量 < 喝水量, 因此除了第一天的情况, 之后的每一天喝完了都一定是可以再加的, 相当于喝水和加水同步进行了, 因此特殊判断第一天是否能加水的情况即可.

​ ③如果x < y, 说明此时我的加水量 > 喝水量, 因此我每天加了水后, 一定够喝. 所以不妨我们就等到晚上水不够喝的时候再去加水(这样可以让(r - 当前水容量) 尽可能大, 更好满足条件.) 此时假设水容量为k(k < x), 然后我给饮水机加水, 使得水容量变为(k + y). 如此反复, 当我们出现一个k’ == k, 此时则会形成一个水容量的循环. 因为x ∈ [1, 1E6], 因此这个循环最多会执行x次.
​ 那么这种情况下:
有两种情况可以满足要求: 计算结果可以满足坚持t天, 水容量出现了循环.
有一种情况不满足要求: 当水容量为k(k < x), 此时 k + y > r.

AC代码

#include <bits/stdc++.h>
#define rep(i, n) for (int i = 1; i <= (n); ++i)
#define debug(a) cout << #a << " = " << a << endl;
using namespace std;
typedef long long ll;
const int N = 1E6 + 10;
bool vis[N];
int main()
{
    ll k, l, r, t, x, y; cin >> k >> l >> r >> t >> x >> y;
    r -= l, k -= l;
    if (x == y) {
        if (k + y <= r) k += y;
        printf("%s\n", k >= x ? "Yes" : "No");
    }
    else if (x >= y) { //用得多
        if (k + y <= r) k += y;
        k -= x;
        
        ll cha = x - y;
        ll day = k / cha;
        printf("%s\n", day + 1 >= t ? "Yes" : "No");
    }
    else {
        do {
            ll day = k / x;
            k -= day * x, t -= min(t, day);
            
            if (vis[k]) break;
            vis[k] = 1;
            
            k += y;
            if (t && k > r) printf("No\n"), exit(0);
        } while(t);
        printf("Yes\n");
    }
    return 0;
}

END

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

逍遥Fau

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

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

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

打赏作者

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

抵扣说明:

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

余额充值