zoukankan      html  css  js  c++  java
  • Hamburgers [CF-371C]

    http://codeforces.com/problemset/problem/371/C

    最好的做法:二分答案。根据枚举的答案判断是否能做出这个数量的汉堡,不断优化答案。(需要注意上边界,不要忘了原有的材料数)。
    代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring> 
    #include<cmath>
    #define LL long long
    using namespace std;
    int nb,ns,nc;
    int pb,ps,pc;
    long long m;
    char a[109];
    int b,s,c;
    bool check(LL x)
    {
        LL need=0;
        if(x*b>nb) need+=(x*b-nb)*pb;
        if(x*c>nc) need+=(x*c-nc)*pc;
        if(x*s>ns) need+=(x*s-ns)*ps;
        if(need<=m) return true;
        else return false;
    }
    int main()
    {
        scanf("%s",a);
        for(int i=0;i<strlen(a);i++)
        {
            if(a[i]=='B') b++;
            else if(a[i]=='C') c++;
            else s++;
        }
        scanf("%d%d%d",&nb,&ns,&nc);
        scanf("%d%d%d",&pb,&ps,&pc);
        scanf("%I64d",&m);
        LL l=0;//min(nb/b,min(nc/c,ns/s));不可以,b,s,c可能是0 
        LL r=m+101;
        if(nc+m/pc<c||nb+m/pb<b||nc+m/pc<c){
            printf("0
    ");
            return 0;
        }
        while(l<=r)
        {
            LL mid=(l+r)>>1;
            if(check(mid))
             l=mid+1;
            else r=mid-1;
        }
        printf("%I64d
    ",r);
        return 0;
    }

    还有一个写起来比较麻烦,但是比较好想的写法,就是贪心。
    尽可能地将原有材料耗光(这个过程中可能要花钱)。
    最后一个整除就可以啦。
    写了三次才过QAQ

    #include<iostream>
    #include<cstdio>
    #include<cstring> 
    #include<cmath>
    #define LL long long
    using namespace std;
    int nb,ns,nc;
    int pb,ps,pc;
    LL m;
    char a[109];
    int b,s,c;
    LL ans;
    int main()
    {
        scanf("%s",a);
        for(int i=0;i<strlen(a);i++)
        {
            if(a[i]=='B') b++;
            else if(a[i]=='C') c++;
            else s++;
        }
        scanf("%d%d%d",&nb,&ns,&nc);
        scanf("%d%d%d",&pb,&ps,&pc);
        scanf("%I64d",&m);
        if(ns+m/ps<s||nb+m/pb<b||nc+m/pc<c){
            printf("0
    ");
            return 0;
        }
        int nedone=b*pb+c*pc+s*ps;
        int dx=100000000;
        if(c) dx=min(dx,nc/c);
        if(s) dx=min(dx,ns/s);
        if(b) dx=min(dx,nb/b);
        ns-=s*dx;nb-=b*dx;nc-=c*dx;
        ans+=dx;
        if(!c) nc=0;if(!b) nb=0;if(!s) ns=0;//防止下面的循环超时!我就在这里TLE过一次
        while(nb||ns||nc)
        {
            int cost=0;
            if(nb>=b) nb-=b;
            else cost+=(b-nb)*pb,nb=0;
            if(nc>=c) nc-=c;
            else cost+=(c-nc)*pc,nc=0;
            if(ns>=s) ns-=s;
            else cost+=(s-ns)*ps,ns=0;
            if(cost>m) break;
            else m-=cost,ans++; 
        }
        ans+=m/nedone;
        printf("%I64d
    ",ans);
        return 0;
    } 
  • 相关阅读:
    WebForms 开发基础
    Web 开发基础
    Winform MDI窗体容器、权限、简单通讯
    Winform TextBox中只能输入数字的几种常用方法(C#)
    WinForm TreeView递归加载
    窗体四边阴影
    winform 进程,线程
    树状数组 / 二维树状数组
    zkw线段树
    [HNOI2014]世界树
  • 原文地址:https://www.cnblogs.com/dfsac/p/7587904.html
Copyright © 2011-2022 走看看