p1374暨2018纪念

  好了今年最后一天,写一个博客好了.

  先说题:

  首先我们打开计算器调到程序员来模拟一下样例:

  

  题意就是对于这个数n如何加上一个新数后使得二进制下的新数1的数量小于等于k

  考虑贪心,设答案是ans,为了让ans最小当然要使得新数最小.每次必须要往上加,那答案应该是把第k个1和之后的1都弄掉,换成这样子:

  这个贪心应该容易想到吧.如果之前没有位置,例如

  且k=5的话为了把最后一个1弄掉不得不换成:

  这个过程有点难写代码实现,我第一次写了个类似模拟一样的东西:

 

循环每一位,由于每次循环后都除以2了,所以只需要判断最低位是否为1就可以了,如果为1就加上1<<i往前推,总会有机会把总的1的个数变少的(check函数是返回n二进制下的1的个数的函数).

  后来我就想到,这个每次找到最后一个1并加一下的操作好像在哪见过啊,lowbit不就是这样的操作么?这样只需要用lowbit就可以快速水过本题了:

using namespace std;
int sum;
int n,k,ans;
inline int lowbit(int kk){
    return kk&(-kk);
}
inline int check(int kk){
    sum=0;
    while(kk){
        sum+=kk&1;
        kk>>=1;
    }
    return sum;
}
int main(){
    cin>>n>>k;
    while(check(n)>k){
        ans+=lowbit(n);
        n+=lowbit(n);
    }
    cout<<ans;    
    return 0;
}
View Code

  复杂度的话,这个过程最多进行log2(n)次,每次的check()函数也是log2(n)的,所以总复杂度是log2^2(n)

  

  我第一篇博客就是今年的1月2号跑到机房写的,当时还啥都不会了,然后寒假在一中集训一下,去省选长见识,去海亮集训一下长见识,停课一个月长见识练能力,NOIP拿到省一等奖都是非常刻骨铭心的体验,感觉一年来飞速的在成长了.具体表现在80篇博客与460道刷题量上.其实拿到省一并且不退役在刚开始学的时候是非常不敢想象的,一点一点走过来之后竟然真的可以,就很开心.

  是不是又要谈学习目标或者说理想了呢?我刚开始学的时候不过是兴趣,后来因为可以天天上qq而坚持了下来,现在应该是为了有一个途径可以考上那个学校了而已吧.

  嗯我会努力去南京大学的,至少可以离大大近一点.

  过几天又要停课了,这次是为了准备省选.好像要停三个月,但是我丝毫不虚.

  大大,我喜欢你啊.

posted @ 2018-12-31 19:05  zzuqy  阅读(192)  评论(0编辑  收藏  举报