C. Water the Trees
题意
题意:给我们n棵树,奇数天的时候我们可以指定的一棵树长高1米,偶数天的时候我们可以让指定的一棵树长高2米,问尽量用最少的天数让n棵树长到一样高,问天数是多少。
思路
思路:这个题我一开始思考的时候是全部的可能的天数求出来用3去凑,但是会发现3的余数的情况不是很好讨论。
我们考虑二分,首先我们假设我们的答案也就是最小的天数是ans,小于ans的天数一定是不行的,然后大于ans的一定是可以的,所以我们的答案是具有单调性的,我们可以二分答案。
那我们其实想要天数最小的话,我们就是要凑的天数就是最大值和最大值加1,然后我们可以把天数分成 m i d − m i d / 2 mid-mid/2 mid−mid/2个1和 m i d / 2 mid/2 mid/2个2,然后我们去凑这个高度,看是否能凑成n棵树完全相等。
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 3e5 + 10;
int a[N];
int n;
bool check(int odd, int even, int maxl)
{
for (int i = 1; i <= n; i++)
{
if (a[i] < maxl)
{
int x = maxl - a[i];
if (x <= even * 2)
{
even -= x / 2;
odd -= x % 2;
}
else
{
x -= 2 * even;
even = 0;
odd -= x;
}
}
if (odd < 0)
return false;
}
return true;
}
void solve()
{
cin >> n;
int Max = 0;
for (int i = 1; i <= n; i++)
cin >> a[i], Max = max(Max, a[i]);
int l = 0, r = 1e18;
while (l < r)
{
int mid = l + r >> 1;
if (check(mid - mid / 2, mid / 2, Max) || check(mid - mid / 2, mid / 2, Max + 1))
r = mid;
else
l = mid + 1;
}
cout << l << endl;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int T;
cin >> T;
while (T--)
{
solve();
}
return 0;
}
总结:我们看最值问题的时候可以考虑二分