[CF1461E] Water Level
Description
饮水机中本来有 \(k\) 升水,John希望在 \(t\) 天内饮水机的水量在 \([l,r]\) 之间,John知道每一天饮水机会被用掉正好 \(x\) 升水,而John可以在一天的开始选择加正好 \(y\) 升水(一天只能加一次)或不加水.给出 \(k,l,r,t,x,y\).求能否在 \(t\) 天内把水量控制在 \([l,r]\).能输出 Yes ,否则输出 No. \(1\leq l\leq k\leq r\leq 10^{18},1\leq t\leq10^{18},1\leq x\leq10^6,1\leq y\leq10^{18}.\)
Solution
分 \(y=x,y<x,y>x\) 三种情况考虑
这里主要说 \(y>x\)
我们尽可能让它减到不能再减,然后加一次
循环的结束条件为 t=0 或者发现水量序列出现了循环节
这是大体的思路,诸多的细节难以详述,见代码
#include <bits/stdc++.h>
using namespace std;
#define int __int128
int t, l, r, k, x, y;
signed main()
{
ios::sync_with_stdio(false);
long long t1, t2, t3, t4, t5, t6;
cin >> t1 >> t2 >> t3 >> t4 >> t5 >> t6;
k = t1;
l = t2;
r = t3;
t = t4;
x = t5;
y = t6;
if (x == y)
{
if (k + y <= r || k - x >= l)
cout << "Yes" << endl;
else
cout << "No" << endl;
}
else if (y < x)
{
if (k + y <= r)
k += y;
int t0 = (k - l - y) / (x - y);
cout << (t0 >= t ? "Yes" : "No") << endl;
}
else
{
if (k + y <= r)
k += y;
set<int> s;
s.insert(k);
while (t > 0)
{
int d = min((k - l) / x, t);
k -= d * x;
t -= d;
if (d == 0)
{
cout << "No" << endl;
return 0;
}
if (s.find(k) != s.end())
{
cout << "Yes" << endl;
return 0;
}
s.insert(k);
if (t == 0)
break;
k += y;
if (k > r)
{
cout << "No" << endl;
return 0;
}
if (s.find(k) != s.end())
{
cout << "Yes" << endl;
return 0;
}
s.insert(k);
if (d == 0)
{
cout << "No" << endl;
return 0;
}
}
cout << "Yes" << endl;
}
}