首页 > 其他分享 >AcWing——凑数(二进制中1的个数)

AcWing——凑数(二进制中1的个数)

时间:2023-06-11 12:33:34浏览次数:50  
标签:凑数 Scanner 二进制 付出代价 System int sc public AcWing

1、题目

初始时,n=0。

每一轮操作都要依次完成两个步骤:

第一步,任选一个非负整数 a,将 n增加 a,这一步所需付出的代价为 a。

第二步,将 n 乘以 2,这一步无需付出任何代价。

你可以不断重复上述操作。

给定一个整数 x,你的任务是使 n 在某一步操作后(不一定是某一轮结束后)恰好等于 x 且付出的总代价尽可能少。

请你计算,为了完成任务所需付出的最小总代价。

例如,如果 x=5,则最佳操作方案为:

第 1 轮操作中,第一步,将 n 增加 1(付出代价 1),使得 n 变为 1,第二步,将 n 乘以 2,使得 n 变为 2。

第 2 轮操作中,第一步,将 n 增加 0(付出代价 0),则 n 仍然为 2,第二步,将 n 乘以 2,使得 n 变为 4。

第 3 轮操作中,第一步,将 n 增加 1(付出代价 1),使得 n 变为 5。此时 n 等于 x 成立,任务完成。

付出的最小总代价为 2。

再例如,如果 x=8,则最佳操作方案为:

第 1 轮操作中,第一步,将 n 增加 1(付出代价 1),使得 n 变为 1,第二步,将 n 乘以 2,使得 n 变为 2。

第 2 轮操作中,第一步,将 n 增加 0(付出代价 0),则 n 仍然为 2,第二步,将 n 乘以 2,使得 n 变为 4。

第 3 轮操作中,第一步,将 n 增加 0(付出代价 0),则 n仍然为 4,第二步,将 n 乘以 2,使得 n 变为 8。此时 n等于 x 成立,任务完成。

付出的最小总代价为 1。

输入格式

一个整数 x。

输出格式

一个整数,表示所需付出的最小总代价。

数据范围

前 3 个测试点满足 1≤x≤10。

所有测试点满足 1≤x≤10⁹。

输入样例1:

5

输出样例1:

2

输入样例2:

8

输出样例2:

1

2、题目解读

看完题目我们知道了加法需要付出代价,乘法不需要付出代价,也就是说我们应该尽量使用乘法去使n变成x。

我们 n(0)->x 可能困难,可是 x->n(0) 就简单了,这时乘法就变成了除法(除以2),而思路就出来了我们应该 使用减法(最小代价就是减1)将x保持成偶数,再x除以二,不断重复上面过程就可以求解出答案。仔细推敲可以发现,就是求 n二进制中 1 的个数。那么这样我们也随便复习一下怎样求二进制中 1 的个数吧!

3、代码

Ⅰ、正常求解

import java.util.Scanner;
 
public class Main {
    public static void main(String[] args) {
         Scanner sc=new Scanner(System.in);
        int n=sc.nextInt();
        int i=0;
        while (n!=0){
            if (n%2==0)
                n/=2;
            else {
                n-=1;
                i++;
            }
        }
        System.out.println(i);
    }
}

Ⅱ、使用Integer.bitCount()方法:这是一种内置于Java的方法,通过调用该方法即可计算一个整数中1的个数。

import java.util.Scanner;
 
public class Main {
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        int n=sc.nextInt();
        System.out.println(Integer.bitCount(n));
    }
}

Ⅲ、可以使用位运算符和循环来计算一个二进制数中1的个数。算法基本思路是将目标数每次右移一位,并且与1进行与运算,如果结果为1,则说明当前位是1,否则为0。循环直到目标数变为0。

import java.util.Scanner;
 
public class Main {
    public static void main(String[] args) {
       Scanner sc=new Scanner(System.in);
        int n=sc.nextInt();
        int count = 0;
        while (n > 0) {
            if ((n & 1) == 1) {
                count++;
            }
            n >>= 1;
        }
        System.out.println(count);
    }
}

Ⅳ、Brian Kernighan算法:该算法是一种优化的常规方法,它的基本思路是利用n&(n-1)可以将n最右边的1变成0的特性,循环直到目标数变为0。

import java.util.Scanner;
 
public class Main {
    public static void main(String[] args) {
       Scanner sc=new Scanner(System.in);
        int n=sc.nextInt();
        int count = 0;
        while (n > 0) {
            n &= (n - 1);
            count++;
        }
        System.out.println(count);
    }
}

标签:凑数,Scanner,二进制,付出代价,System,int,sc,public,AcWing
From: https://blog.51cto.com/u_15409921/6457417

相关文章

  • 【蓝桥杯集训·周赛】AcWing 第96场周赛
    第一题AcWing4876.完美数一、题目1、原题链接4876.完美数2、题目描述如果一个正整数能够被2520整除,则称该数为完美数。给定一个正整数n,请你计算[1,n]范围内有多少个完美数。输入格式一个整数n。输出格式一个整数,表示[1,n]范围内完美数的个数。数据范围前3个测试点满......
  • 【蓝桥杯集训·周赛】AcWing 第 95 场周赛
    第一题AcWing4873.简单计算一、题目1、原题链接4873.简单计算2、题目描述给定四个整数x1,y1,x2,y2,请你计算max(|x1−x2|,|y1−y2|)。输入格式第一行包含两个整数x1,y1。第二行包含两个整数x2,y2。输出格式一个整数,表示max(|x1−x2|,|y1−y2|)的值。数据范围前4个测试点......
  • 2、Docker二进制安装脚本
    #!/bin/bashDOCKER_VERSION=20.10.19#URL=https://mirrors.aliyun.comURL=https://download.docker.comprepare(){if[!-edocker-${DOCKER_VERSION}.tgz];then#wget${URL}/docker-ce/linux/static/stable/x86_64/docker-${DOCKER_VERSION}.tgz......
  • 1、Docker二进制安装脚本
    #!/bin/bashDOCKER_VERSION=20.10.19#URL=https://mirrors.aliyun.comURL=https://download.docker.comprepare(){if[!-edocker-${DOCKER_VERSION}.tgz];then#wget${URL}/docker-ce/linux/static/stable/x86_64/docker-${DOCKER_VERSION}.tgz......
  • 51存储器块清零和二进制数转换成二十进制(BCD)码
    一、实验目的1、了解单片机实验开发板电路原理图2、掌握KEIL软件开发单片机C51程序的流程3、掌握单片机开发程序的烧录方法和流程二、实验内容1、完成单片机开发相关必备软件的安装2、学习单片机开发板套件的实验原理图3、编写、下载及实现第一个单片机程序(点亮一个LED灯)三......
  • AcWing——砝码称重
    4942.砝码称重-AcWing题库1、题目给定一个天平和101个砝码。101个砝码的重量依次为n⁰,n¹,n²,…,n¹⁰⁰克,其中n是一个不小于2的整数。请你判断,我们能否利用给定天平和砝码对重量为m克的物品进行称重。注意,天平的两端都可以放入砝码。具体来说,你的任务是判断是否可......
  • mysql8.0二进制安装遇到的问题
    公司新项目需要用CentOS8.0以上的系统和mysql8.0;于是在虚拟机上开始操作测试;一实验环境1、系统版本:CentOS8.32、数据库版本:mysql-8.0.233、数据库下载链接:https://dev.mysql.com/downloads/mysql/二、遇到的问题这里不讲安装过程,之前博客有写只不过用的是mysql5.7,安装过......
  • 【MySQL】二进制安装MySQL
    一、基于Ubuntu二进制安装MySQL8.0(5.7+适用)1、创建用户[root@Node-Ubuntu1804-20:~]#groupaddmysql[root@Node-Ubuntu1804-20:~]#useradd-r-gmysql-s/usr/sbin/nologinmysql 2、创建目录[root@Node-Ubuntu1804-20:~]#mkdir/data/mysql-p[root@Node-Ubunt......
  • 【acwing】Trie字符串统计
    Trie树学习感受相比于之前学习的kmp匹配算法,Trie树的实现还是非常好理解的。(kmp算法太难了orz)从直观的模拟过程来看,trie树就像一颗树一样,从上(根节点)到下(叶节点)有序串联起来组成一个字符串。每一个额外标记结束的位置表示字符串的结束,通过计算标记数即可指导一共有多少该字符串......
  • 【每日一题】AcWing 1904. 奶牛慢跑
    题目奶牛们又出去锻炼蹄子去了!有N头奶牛在无限长的单行道上慢跑。每头奶牛在跑道上开始奔跑的位置互不相同,一些奶牛的奔跑速度可能相同,也可能不同。由于跑道是单行道,十分狭窄,奶牛们无法相互超越。当一头速度很快的牛追上另一头牛时,她必须减速至与另一头牛速度相同以免发生碰撞,并成......