zoukankan      html  css  js  c++  java
  • Code+ B 汀博尔【二分答案】

    时间限制:C/C++ 1秒,其他语言2秒
    空间限制:C/C++ 262144K,其他语言524288K
    64bit IO Format: %lld

    题目描述

    有 n 棵树,初始时每棵树的高度为 Hi,第 i 棵树每月都会长高 Ai。现在有个木料长度总量为 S 的订单,客户要求每块木料的长度不能小于L,而且木料必须是整棵树(即不能为树的一部分)。现在问你最少需要等多少个月才能满足订单。

    输入描述:

    第一行 3 个用空格隔开的非负整数 n,S,L,表示树的数量、订单总量和单块木料长度限制。
    第二行 n 个用空格隔开的非负整数,依次为 H1,H2,... ,Hn。
    第三行 n 个用空格隔开的非负整数,依次为 A1,A2,... ,An。

    输出描述:

    输出一行一个整数表示答案。
    示例1

    输入

    3 74 51
    2 5 2
    2 7 9

    输出

    7

    说明

    对于样例,在六个月后,各棵树的高度分别为 14,47,56,此时无法完成订单。
    在七个月后,各棵树的高度分别为 16,54,65,此时可以砍下第 2 和第 3 棵树完成订单了。

    备注:

    1≤n≤200000,1≤S,L≤1018,1≤Hi,Ai≤109

    【分析】:二分答案。上界不能直接选择1e18,会爆long long。根据一棵树能完成需求的时间最小值不断降低时间。
    【代码】:
    #include <bits/stdc++.h>
    #define LL long long
    #define maxn 200005
    
    using namespace std;
    LL a[maxn],h[maxn],S,L,mx;
    int n;
    
    bool check(LL day)
    {
        LL ans=0;
        LL now;
        for(int i=1;i<=n;i++)
        {
            now = a[i]*day+h[i];//x是天数,a是步长(增量)一个一个的增,增完下一个
            if(now>=L) ans+=now;
            if(ans>=S) return true;
        }
        return false;
    }
    int main()
    {
        cin>>n>>S>>L;
        for(int i=1;i<=n;i++) cin>>h[i];
        for(int i=1;i<=n;i++) cin>>a[i],mx=max(mx,max(L,S)/a[i]);
        LL l=0,r=mx,ans=0;
        while(l<=r)
        {
            LL mid=(l+r)>>1;
            if(check(mid)) r=mid-1;
            else l=mid+1;
        }
        cout<<l<<endl;
    }
    View Code

    #include<iostream>
    #include<set>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    
    typedef unsigned long long ll;
    
    ll h[2000010],a[2000010];
    ll sum;
    int main()
    {
        ll n,S,L,i,j,l,r,m;
        while(cin>>n>>S>>L)
        {
            l=0;r=1e18;m=(l+r)/2;
            for(i=0;i<n;i++)
                scanf("%d",&h[i]);
            for(i=0;i<n;i++)
                scanf("%d",&a[i]);
            while(l<r)
            {
                sum=0;
                for(i=0;i<n;i++)
                {
                    ll x=h[i]+m*a[i];
                    if(x>=L)
                         sum+=x;
                    if(sum>=S)
                    break;
                }
                if(sum>=S)
                {
                    r=m;
                }
                else
                {
                    l=m+1;
                }
                m=(l+r)/2;
            }
            cout<<m<<"
    ";
        }
        return 0;
    }
    易懂
    #include <cstdio>
    #include <algorithm>
    using namespace std;
    typedef long long ll;
    int n;
    ll s,l;
    ll h[200100],a[200100];
    int check(ll mid)
    {
        ll sum=0;
        for(int i=1;i<=n;i++)
        {
            if(h[i]+a[i]*mid>=l) sum+=(h[i]+a[i]*mid);
            if(sum>=s) return 1;
        }
        return 0;
    }
    ll maxx;
    int main()
    {
        scanf("%d%lld%lld",&n,&s,&l);
        for(int i=1;i<=n;i++) scanf("%lld",&h[i]);
        for(int i=1;i<=n;i++) scanf("%lld",&a[i]),maxx=max(maxx,a[i]);
        ll l=0,r=1e18/maxx,mid,ans=0;
        while(l<=r)
        {
            mid=(l+r)/2;
            if(check(mid)) r=mid-1,ans=mid;
            else l=mid+1;
        }
        printf("%lld",ans);
    }
    View Code2
  • 相关阅读:
    贪心:SPOJ Backup Files
    杂题 SPOJ MOBILE2
    杂题 UVAoj 10000 Longest Paths
    杂题 UVAoj 107 The Cat in the Hat
    DP(斜率优化):HDU 3507 Print Article
    搜索(DLX): POJ 3074 3076 Sudoku
    DLX模板
    PHP代码优化技巧大盘点
    盘点PHP编程常见失误
    PHP Socket 编程详解
  • 原文地址:https://www.cnblogs.com/Roni-i/p/7909831.html
Copyright © 2011-2022 走看看