[CodeForces - 1225C]p-binary 【数论】【二进制】

[CodeForces - 1225C]p-binary 【数论】【二进制】


题目描述

Time limit
2000 ms
Memory limit
524288 kB
Source
Technocup 2020 - Elimination Round 2
Tags
bitmasks brute force math *1600
Site
https://codeforces.com/problemset/problem/1225/c

题面

Example
Input1

24 0

Output1

2

Input2

24 1

Output2

3

Input3

24 -1

Output3

4

Input4

4 -7

Output4

2

Input5

1 1

Output5

-1

题目大意

给定\(n, p\),使\(n\)能表达成这样的形式\(n = \sum_{i = 1}^{m}(2^{a[i]} + p)\)(\(a[i] = 0,1,2,3, \dots\))。问最小的\(m\)是多少?如果无法写成上述表达,则输出-1。

例如,
给定\(n = 24, k = 1\),\(24 = (2^4 + 1) + (2^2 + 1)+ (2^0 + 1)\)。这样\(m\)最小为3。


解析

可将上式变形,\(n - m \times p = \sum_{i = 1}^{m}2^{a[i]}\)。

令\(d(x)\)表示\(x\)的二进制形式中\(1\)的个数。
我们不难发现,满足\(d(n - m \times p) \leq m \leq n - m \times p\),即有\(n - m \times p = \sum_{i = 1}^{m}2^{a[i]}\)。
因为\(2^i = 2^{i - 1} + 2 ^ {i - 1}\),所以\(m\)可以大于这个数的二进制中\(1\)的个数。
而\(2^0 = 1\)的时候就无法再往下分了,所以\(m\)要小于等于这个数的本身。

这样我们就可以通过简单枚举\(m\)得出答案。

为什么m可以通过枚举得出?m不会很大吗?
\(n - m \times p = \sum_{i = 1}^{m}2^{a[i]}\)等式左边是线性增长,等式右边是指数增长。能使等号成立的\(m\)不会很大。


通过代码

/*
Status
    Accepted
Time
    31ms
Memory
    8kB
Length
    584
Lang
    GNU G++11 5.1.0
Submitted
    2019-12-20 09:17:54

RemoteRunId
    67258530
*/

#include <bits/stdc++.h>
#define lowbit(i) i & -i                //一个数的二进制表示中,1的最低位.
using namespace std;

const int INF = 1e5;
int n, p;

int binary_digit(int x)            //找到一个数的二进制表示中,有几个1.
{
    int cnt = 0;

    while(x){
        x -= lowbit(x);
        cnt ++;
    }

    return cnt;
}
void work()
{
    for(int i = 1; i < INF; i ++){      //枚举.
        if(n - i * p < 0){              //n>0,出现小于0的情况就直接结束.
            puts("-1");
            return;
        }

        if(binary_digit(n - i * p) <= i && i <= n - i * p){    //落在这个区间的就能满足等式.
            printf("%d", i);
            return;
        }
    }

    puts("-1");
    return;
}
int main()
{
    scanf("%d%d", &n, &p);

    work();

    return 0;
}


[CodeForces - 1225C]p-binary 【数论】【二进制】

原文地址:https://www.cnblogs.com/satchelpp/p/12074810.html

时间: 2024-08-07 20:34:19

[CodeForces - 1225C]p-binary 【数论】【二进制】的相关文章

【LeetCode-面试算法经典-Java实现】【067-Add Binary(二进制加法)】

[067-Add Binary(二进制加法)] [LeetCode-面试算法经典-Java实现][所有题目目录索引] 原题 Given two binary strings, return their sum (also a binary string). For example, a = "11" b = "1" Return "100" 题目大意 给定两个二进制的字符串,返回它们的和,也是二进行制字符串. 解题思路 先将对应的两个二进制字符串

UVa 575 Skew Binary 歪斜二进制

呵呵,这个翻译还是很直白的嘛,大家意会就好. 第一次看到这个高大上题目还是有点小害怕的,还好题没有做过深的文章. 只要按照规则转化成十进制就好了,而且题目本身也说了最大不超过一个int的范围(2^31-1 == 2147483647). 直接位运算就好了.   Skew Binary  When a number is expressed in decimal, the k-th digit represents a multiple of 10k. (Digits are numbered f

Codeforces 309C Memory for Arrays 二进制模拟进位

题目链接:点击打开链接 题意: 给定n个箱子m个物品 下面n个数字表示箱子的容量 下面m个数字b1-bm 表示物品体积为2^bi大 问最多有多少个物品可以放入箱子. 思路: 贪心,先放小的,小的不能放再放大的 显然我们把n个箱子拆成二进制,然后模拟二进制减法运算. 剩下就是简单模拟 #include<stdio.h> #include<string.h> #include<iostream> #include<algorithm> #include<m

Codeforces 413B Spyke Chatting(数论简单)

题目链接:Codeforces 413B Spyke Chatting 题目大意:n个人,m种聊天器,k次发送消息,然后给出n*m的矩阵,如果g[i][j]为1,则表示i号人会使用j号聊天器,接着给出k次消息发送者和聊天器,如果i在j种聊天器上发送了一条消息,那么所有使用j种聊天器的人都会接受到消息.现在要求每个人会接受到几条消息,自己发送的不算. 解题思路:分别记录每个聊天器上有多少个消息,以及每个人发送了多少条消息,然后计算每个人接受到多少条消息的时候只要将这个人所使用的各个聊天器消息数取和

LeetCode OJ:Add Binary(二进制相加)

Given two binary strings, return their sum (also a binary string). For example,a = "11"b = "1"Return "100". 简单的二进制相加而已,只不过传入的参数是字符串而已.为了方便,先将string  reverse了一下,代码如下: 1 class Solution { 2 public: 3 string addBinary(string a, s

LeetCode 67 Add Binary(二进制相加)(*)

翻译 给定两个二进制字符串,返回它们的和(也是二进制字符串). 比如, a = "11" b = "1" 返回 "100". 原文 Given two binary strings, return their sum (also a binary string). For example, a = "11" b = "1" Return "100". 分析 我一開始写了这个算法,尽管实现

LeetCode 67. Add Binary (二进制相加)

Given two binary strings, return their sum (also a binary string). For example,a = "11"b = "1"Return "100". 题目标签:Math 题目给了我们两个string a 和 b,让我们把这两个二进制 相加. 首先把两个string 的长度得到,然后从右向左 取 两个string 的 digit. 增设一个 carry = 0: 每一轮把 digit

762. Prime Number of Set Bits in Binary Representation 二进制表示形式中的素数位数

Given two integers L and R, find the count of numbers in the range [L, R] (inclusive) having a prime number of set bits in their binary representation. (Recall that the number of set bits an integer has is the number of 1s present when written in bin

CodeForces - 1225C p-binary(思维)

题目链接: http://codeforces.com/problemset/problem/1225/C 思路 把所有的p移回左边得到一个数, 此时它应该有多个\({2^k}\) 组成 然后我们就可以数出这个数的二进制及有多少个1 判断它是不是符合题意 Code #include <bits/stdc++.h> using namespace std; #define LL long long #define popcount __builtin_popcount int main() {