Div2(317C)Div2(219) B 二分法判定

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <string.h>
#include <vector>
#include <queue>
#define LL long long    //Div2 (218C)二分法判定
using namespace std;
LL a, b, c, s1, s2, s3, p1, p2, p3, k;
LL max1(LL a1, LL b1)
{
	if(a1>b1)return a1;
	else return b1;
}
bool f(LL x)  //x是汉堡包的个数
{
	LL x1=x*a, x2=x*b, x3=x*c, s;  //x1, x2, x3是各项材料总共需要多少
	s=max1(0,(x1-s1)*p1)+max1(0,(x2-s2)*p2)+max1(0,(x3-s3)*p3);//剩下的材料所需要的钱
	if(s>k)return false;
	else return true;
}
int main()
{
	int t, j;
	LL l, r, mid, ans;
	char p[110];
	while(scanf("%s", p)!=EOF)
	{
		j=strlen(p);
		for(t=0, a=b=c=0; t<j; ++t)
		{
			if(p[t]=='B')
				a++;
			if(p[t]=='S')
				b++;
			if(p[t]=='C')
				c++;
		}
		scanf("%I64d%I64d%I64d", &s1, &s2, &s3);
		scanf("%I64d%I64d%I64d", &p1, &p2, &p3);
		scanf("%I64d", &k);
		l=ans=0;
		r=10000000000000;  //这里要取比1e12更大的数
		while(l<=r)   // 二分法判定,枚举汉堡包的个数
		{
			mid=(l+r)>>1;
			if(f(mid))
			{
				ans=mid;
				l=mid+1;
			}
			else r=mid-1;
		}
		printf("%I64d\n", ans);
	}
	return 0;
}



#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <string.h>
#include <vector>
#include <queue>
#define LL long long   //Div2(219)  B 二分
using namespace std;
LL w, m, k;
LL num1(LL x)
{
	LL s=0;
	while(x)
	{
		x=x/10;
		s=s*10+9;	
	}
	return s;
}
LL num2(LL x)
{
	LL t=0;
	while(x)
	{
		t++;
		x=x/10;
	}
	return t;
}
bool f(LL x)
{
	LL b, s, t, k1, k2, g, j;	
	k1=num1(m);
	k2=k1-m+1;
	g=num2(m);
	if(k2>=x)
	{
		s=x*k*g;
		if(s<=w&&s>=0)return true;   //防止越界
		else return false;
	}
	s=k*k2*g;
	x=x-k2;
	for(j=0, t=9; j<g; ++j)
		t*=10;
	b=g+1;
	while(t<=x)
	{
		s=s+t*k*b;
		b++;
		x=x-t;
		t=t*10;
	}
	if(x)s+=x*b*k;
	if(s<=w)return true;
	else return false;
}

int main()
{
	LL l, r, ans, mid;
	while(scanf("%I64d%I64d%I64d", &w, &m, &k)!=EOF)
	{
		l=0;
		r=1000000000000000;
		while(l<=r)
		{
			mid=(l+r)>>1;
			if(f(mid))
			{
				ans=mid;
				l=mid+1;
			}
			else r=mid-1;
		}
		printf("%I64d\n", ans);
	}
	return 0;
}


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <string>
#include <vector>
#include <queue>
#define N 100010
using namespace std;  
#define LL long long  //CF211 Div2 (D)  二分、贪心
LL a, b[N], c[N];   //注意这里要定义成long long
bool cmp(LL a1, LL b1)
{
	return a1>b1;
}

bool f(LL x)
{
	LL t, j, s=0;
	for(j=x-1, t=0; t<x; --j, ++t)
	{
		if(b[j]>=c[t])continue;     //先钱少的人来付最便宜的车,这样效果最好
		s=s+c[t]-b[j];
	}
	if(s<=a)return true;
	else return false;
}

int main()
{
	int n, m, t;
	LL s;
	while(scanf("%d%d%I64d", &n, &m, &a)!=EOF)
	{
		for(t=0; t<n; ++t)
			scanf("%I64d", b+t);
		sort(b, b+n, cmp);   //每个人的钱按递减的顺序排,贪心
		for(t=0; t<m; ++t)
			scanf("%I64d", c+t);
		sort(c, c+m);  //价格按递增的顺序排
		int l=0, r=n, mid, ans;
		while(l<=r)
		{
			mid=(l+r)>>1;
			if(mid<=m&&f(mid))   //注意这里车的数量要和人匹配,不能少于人
			{
				ans=mid;
				l=mid+1;
			}
			else r=mid-1;
		}
		if(ans==0)
		{
			printf("0 0\n");
			continue;
		}
		for(t=0,s=0; t<ans; ++t)
			s+=c[t];
		if(s<a)printf("%d 0\n", ans);
		else printf("%d %I64d\n", ans, s-a);
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值