您的位置:首页 > 其它

二分答案:Poweroj2461-入门基础之二分答案(二分法的应用)

2017-07-02 19:36 447 查看
传送门:点击打开链接                                                                                                  ###入门基础之二分答案
Time Limit: 1000 MS Memory Limit: 65536 KB
Total Submit: 179 Accepted: 33 Page View: 744
Submit Status Discuss
####Description
M78喜欢积木,更喜欢机器人。于是,他决定用积木组装机器人。积木总共有三种,做一个机器人需要三种类型的积木分别a,b,c个。现在,他分别有这三种积木x,y,z个。另外,他还有一些金币。他总共有sum个金币,他可以用这些金币购买积木,购买这三种积木分别会花费c1,c2,c3金币。M78想尽可能地多做一些机器人,问,他最多能做多少个机器人?
####Input
多组输入。每组输入共三排。
第一排,三个整数a,b,c。(1<=a,b,c<=100)
第二排,三个整数x,y,z。(0<=x,y,z<=100)
第三排,四个整数sum,c1,c2,c3。(0<=sum<=10^12,1<=c1,c2,c3<=100)
符号的意义同题目描述中一样。
####Output
对于每组,输出一排,这排只有一个整数,表示M78能组装的最多的机器人数。
####Sample Input
1 2 3
100 100 100
300 7 8 9
####Sample Output
44

解题心得:1、一开始在做这个题的时候就知道是使用二分法求解,但是怎么二分其实是有技巧的,首先先将所有的积木变成金钱,然后使用金钱去除制作一个机器人要花费的金钱的到的就是二分法的上限,而使用现在有的积木能有做出来的最少的机器人的个数就是二分法的下限,然后使用二分法看现在所剩余的金钱是否可以制作出二分的得到的个数的机器人,然后二分就可以了。2、二分的界限,即最后一个mid总是弄不清楚,然后就没办法只有自己检查了。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll a,b,c,x,y,z,sum1,c1,c2,c3;
ll sum,Start,End;

bool check(ll m)//检查是否可以做m个机器人
{
ll Sum = 0;
ll v1,v2,v3;
v1 = (m*a - x)*c1;
v2 = (m*b - y)*c2;
v3 = (m*c - z)*c3;
if(v1 > 0)
Sum += v1;
if(v2 > 0)
Sum += v2;
if(v3 > 0)
Sum += v3;
if(Sum > sum1)
return false;
else
return true;
}

void get_Start()//得到二分的下限
{
ll Min = 0x7f7f7f7f;
if(x/a < Min)
Min = x/a;
if(y/b < Min)
Min = y/b;
if(z/c < Min)
Min = z/c;
Start = Min;
}

void get_End()//得到二分的上限
{
sum = sum1 + x*c1 + y*c2 + z*c3;
End = sum/(a*c1 + b*c2 + c*c3);
}

void get_ans()
{
ll Mid = (Start + End)/2;
while(1)
{
Mid = (Start + End)/2;
if(check(Mid) && !check(Mid + 1))
break;
if(!check(Mid))
End = Mid - 1;
else
Start = Mid + 1;
}
printf("%lld\n",Mid);
}
int main()
{
while(scanf("%lld%lld%lld%lld%lld%lld%lld%lld%lld%lld",&a,&b,&c,&x,&y,&z,&sum1,&c1,&c2,&c3)!=EOF)
{

get_Start();
get_End();
get_ans();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: