zoukankan      html  css  js  c++  java
  • 洛谷p1582倒水(思维好题,数学,2进制问题,代码实现)

    题目链接:https://www.luogu.org/problemnew/show/P1582

    题目猛一看挺难想,但想通了加的原理和合并的原理后就好说了。

    肯定和2进制是紧密相连的,每个瓶子的水升数一定是2的倍数(因为每次合的都是一样的且都是2的倍数)

    看透了这题后本质就是:将一个整数不断分解成2进制的表达形式存起来,再从后往前合并(每次ans加上前后两数之差就可以相等合并)<m时退出即可!

    另外一个技巧是:算2的次幂不用每次都算,完全可以打表(很方便还省下不少时间)

     1 #include <iostream>
     2 #include <algorithm>
     3 typedef long long ll;
     4 using namespace std;
     5 ll b[70];
     6 ll t[70];
     7 ll n,m;
     8 
     9 void bit()
    10 {
    11     b[0]=1;
    12     for(int i=1;i<=62;i++)
    13     {
    14         b[i]=b[i-1]*2;
    15     }
    16 }
    17 
    18 void sol()
    19 {
    20     ll x=n;
    21     int k=0,p=0;
    22     while(x)
    23     {
    24         for(int i=0;i<=70;i++)
    25         {
    26             if(b[i]>x)
    27             {
    28                 x-=b[i-1];
    29                 //cout<<b[i-1]<<' ';//观察分解数,挺有用.
    30                 t[++p]=b[i-1];
    31                 k++;
    32                 break;
    33             }
    34         }
    35     }
    36     //cout<<endl;
    37     
    38     if(k<=m)
    39     {
    40         cout<<"0"<<endl;
    41         return;
    42     }
    43     
    44     ll ans=0;
    45     for(int i=p;i>=1;)
    46     {
    47         ans+=t[i-1]-t[i];
    48         i--;
    49         t[i]=t[i]*2;
    50         
    51         k--;
    52         if(k<=m) break;
    53     }
    54     cout<<ans<<endl;
    55 }
    56 
    57 int main()
    58 {
    59     bit();
    60     
    61     cin>>n>>m;
    62     
    63     sol();
    64     
    65     return 0;
    66 }

    完。

  • 相关阅读:
    ASP.NET 下载文件方式
    分享各大平台接口(空间,微博)
    BitmapToASCii
    C#操作进程(Process)
    Config ConnectionStrings
    Import Excel void (NPOI)
    C# Serialize
    C# 属性
    调用存储过程的方法
    Redis配置与安装
  • 原文地址:https://www.cnblogs.com/redblackk/p/9940582.html
Copyright © 2011-2022 走看看