CodeForces 371C & CodeForces 343C 二分

CodeForces 371C & CodeForces 343C

题目

CF 371C
CF 343C

思路

二分答案,主要是judge的代码要想好怎么写
371C二分答案直接看是否合适
343C二分答案,pos记录最小未被覆盖的点的下标,然后两种方法,1.贪心先左到pos,2.贪心向右走到(mid - (h[i] - pos[i]))/2再向左走,因为这样保证能到达pos的位置,最后取向右走的最大值然后二分找下一个pos

代码

371C

#include <iostream>
#include <cstdio>
#include <set>
#include <list>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <string>
#include <sstream>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <cctype>
#include <cmath>
#include <fstream>
#include <iomanip>
//#include <unordered_map>
using namespace std;
#define dbg(x) cerr << #x " = " << x << endl;
typedef pair<int, int> P;
typedef long long ll;
#define FIN freopen("in.txt", "r", stdin);
string op;
int main()
{
   // FIN;
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int nb, ns, nc, pb, ps, pc;
    cin >> op;
    cin >> nb >> ns >> nc >> pb >> ps >> pc;
    int b = 0, s = 0,c = 0;
    ll p;
    cin >> p;
    for(int i = 0; i < op.size(); i++)
    {
        if(op[i] == 'B') b++;
        if(op[i] == 'S') s++;
        if(op[i] == 'C') c++;
    }
    ll l = 0;
    ll r = 2e12;
    ll ans ;
    while(l < r)
    {
        //dbg(l);
        //dbg(r);
        ans = (l + r) >> 1;
        ll resb = b * ans - nb;
        ll ress = s * ans - ns;
        ll resc = c * ans - nc;
        //cout << resb << ' ' << ress << ' ' << resc <<endl;
        ll tot = max(resb, 0LL) * pb + max(resc, 0LL) * pc + max(ress, 0LL) * ps;
        //dbg(tot);
        if(tot > p)
        {
            r = ans;
        }
        else
        {
            l = ans + 1;
        }
        
    }
    cout << l - 1 << endl;
}

343C

#include <iostream>
#include <cstdio>
#include <set>
#include <list>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <string>
#include <sstream>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <cctype>
#include <cmath>
#include <fstream>
#include <iomanip>
//#include <unordered_map>
using namespace std;
#define dbg(x) cerr << #x " = " << x << endl;
typedef pair<int, int> P;
typedef long long ll;
#define FIN freopen("in.txt", "r", stdin);
const int MAXN = 1e5+5;
ll h[MAXN];
ll p[MAXN];
int n, m;
int judge(ll mid)
{
	ll pos = 0;
	for(int i = 0; i < n; i++)
	{
		ll x= mid;
		if(h[i] >= p[pos])
		{
			if(mid >= h[i] - p[pos])
			{
				x = max(0LL, max(mid - 2 * (h[i] - p[pos]), (mid - h[i] + p[pos]) / 2));
			}
			else
			return 0;
		}
		pos = upper_bound(p, p + m, x + h[i]) - p;
		if(pos == m) return 1;
	}
	return 0;
}

int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    cin >> n >> m;
    for(int i = 0; i < n ; i++)
    {
    	cin >> h[i];
	}
	for(int i = 0; i < m; i++)
	{
		cin >> p[i];
	}
	ll l = 0, r = 1e12;
	ll mid;
	ll ans = 0;
	while(l < r)
	{
		mid = (l + r) >> 1;
		if(judge(mid))
		{
			r = mid;
		}
		else
		{
			l = mid + 1;
		}
	}
	cout << r << endl;
}

总结

什么时候能使用二分答案,这是思考的重点,看起来应该是如果无法用特殊的办法求出答案,每一种答案都需要暴力来验证细节,验证答案的准确性,比如371C我们无法通过暴力去找到合适的汉堡数量,而价格和答案又有正相关的关系,再例如343C中,我们无法bfs去找到最好的时间,而答案和移动的距离又是正相关的,那么可以考虑一下二分答案,然后去验证一下。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值