codeforces1303B National Project 二分或直接计算

网址:https://codeforces.com/contest/1303/problem/B

题意:

修一条长度为$n$的路,要求至少一半是$good$的。在一个周期中,第$[1,g]$天可以修$good$的路,第$[g+1,g+b]$天可以修$bad$的路,依次交替。问按要求修完整条路需要的最短时间。

题解:

解法1:

直接计算。先考虑$g

AC代码:

#include 
using namespace std;
typedef long long ll;
void solve()
{
	ll n, g, b;
	scanf("%lld%lld%lld", &n, &g, &b);
	ll tmp = (n + 1) / 2;
	ll tot = tmp / g * (g + b);
	if (tmp % g == 0)
		tot -= b;
	else
		tot += tmp % g;
	printf("%lld\n", max(tot, n));
}
int main()
{
	int t;
	scanf("%d", &t);
	while (t--)
		solve();
	return 0;
}

 $*$向上取整的整数除法写法是$(x+n-1)/n$。

解法2:

二分就是判断给出的$t$天能不能完成这个工程,显然如果$t$天中$good$的天数都不够$\lceil n/2 \rceil$的肯定不行,否则就可以,二分的下界是$n$,上界直接$INF$,不差那点时间。

AC代码:

#include 
using namespace std;
const int N = 1e5 + 5;
typedef long long ll;
bool check(ll n, ll g, ll b, ll t)
{
	return (n + 1) / 2 <= t / (g + b) * g + min(g, t % (g + b));
}
void solve()
{
	ll n, g, b;
	scanf("%lld%lld%lld", &n, &g, &b);
	ll l = n, r = 1e18;
	while (l < r)
	{
		ll m = (l + r) >> 1;
		if (check(n, g, b, m))
			r = m;
		else
			l = m + 1;
	}
	printf("%lld\n", l);
}
int main()
{
	int t;
	scanf("%d", &t);
	while (t--)
		solve();
	return 0;
}

 

你可能感兴趣的:(codeforces1303B National Project 二分或直接计算)