牛客小白月赛32--C消减整数、E春游(贪心)

C、消减整数

链接:https://ac.nowcoder.com/acm/contest/11163/C
来源:牛客网
题意:给出一个正整数H,从1开始减,第一次必须减1,每次减的数字都必须和上一次相同或者是上一次的两倍,请问最少需要几次能把H恰好减到0。

思路:这个题目我们应该从给定的H是奇数还是偶数入手,除了1以外,所减的数必定为偶数。因此我们讨论如下:

  • 当H为偶数时,为了能够成功减到0,那么必定是减了两次1;
  • 当H为奇数时,为了使得减到0的次数最少,所以减了一次1;

在上面处理以后确保H为偶数,然后开始循环,倘若H能够被当前减数的2倍整除,那么就减去2倍的减数,否则减去当前的减数不变。(注意,如果这里的条件变为:H大于当前减数的2倍,那么久减去减数的2倍则会超时!!)

代码:

#include <bits/stdc++.h>
using namespace std;
int main()
{
    int T,i;
    int H,num;
    scanf("%d",&T);
    while (T--)
    {
        num=0;
        i=1;
        scanf("%d",&H);
        if(H%2==0){
            H-=2;
            num+=2;
        }else{
            H-=1;
            num++;
        }
        while (H)
        {
            if(H%(i*2)==0)
            {
                num++;
                i*=2;
                H-=i;
            }else
            {
                H-=i;
                num++;
            }
            
        }
        cout<<num<<endl;
    }
    system("pause");
    return 0;       
}

 

 

E、春游

链接:https://ac.nowcoder.com/acm/contest/11163/E
来源:牛客网
双人船最多坐两人,也可以坐一人,收费a元

三人船最多坐三人,也可以坐两人或者一人,收费b元

本次出游加上带队老师共n人,如何安排能使得花费最小呢?

思路:贪心。我们尽可能选择单价(每个人平摊多少钱)小的,那么则会出现以下几种情况:

  • 1、当双人船单价小于三人船单价,这时候我们尽可能安排双人船坐满。倘若人数恰好是偶数,那么直接全部使用双人船即可。倘若剩余1人,则有两种情况:(1)安排双人船和三人船收费较少的一个(2)撤下一艘双人船,让撤下的两人和剩余的1人共同乘坐一个三人船。这两种情况去较小即可。
  • 2、当三人船的单价小于双人船,这时候我们安排三人船尽可能的坐满。那么最后可能会剩余1人,或者两人,分情况进行讨论:
    • (1)当剩余1人的时候,可以选择双人船和三人船较小的一个让其单独乘坐;或者撤下一艘三人船,换用两艘双人船。两者取最小
    • (2)当剩余2人的时候,同样可以选择双人船和三人船较小的一个让其这两个人单独乘坐;或者撤下一艘三人船,换用3搜双人船。两种情况取最小

最后,一定不要忘记当n小于2的情况,即直接选择两者较小的即可。代码如下:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
{
    ll T;
    ll n,a,b;
    ll ans;
    cin>>T;
    while(T--)
    {
        cin>>n>>a>>b;
        if(n<=2){
            cout<<min(a,b)<<endl;
            continue;
       }
       ll aa = a/2;
       ll bb = b/3;
        if(aa>bb){
            ans=(n/3)*b;
            if(n%3==1)
            {
                ans = min({ans+min(a,b),ans-b+2*a});
            }else if(n%3==2)
            {
                ans = min({ans+min(a,b),ans-b+3*a});
            }
        }else{
            ans = (n/2)*a;
            if(n%2==1)
            {
               ans = min({ans+min(a,b),ans-a+b});
            }
        }
        cout<<ans<<endl;
    }
    system("pause");
    return 0;
}

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值