Round Numbers【数位DP】

本文介绍了一种基于二进制表示的数字游戏,奶牛们通过选择特定范围内的“圆数”来决定胜负。圆数定义为二进制表示中零的数量不少于一的数量的正整数。文章提供了一个算法解决方案,用于计算给定范围内圆数的数量,通过递归深度优先搜索策略,结合动态规划优化计算过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

The cows, as you know, have no fingers or thumbs and thus are unable to play Scissors, Paper, Stone' (also known as 'Rock, Paper, Scissors', 'Ro, Sham, Bo', and a host of other names) in order to make arbitrary decisions such as who gets to be milked first. They can't even flip a coin because it's so hard to toss using hooves.

They have thus resorted to "round number" matching. The first cow picks an integer less than two billion. The second cow does the same. If the numbers are both "round numbers", the first cow wins,
otherwise the second cow wins.

A positive integer N is said to be a "round number" if the binary representation of N has as many or more zeroes than it has ones. For example, the integer 9, when written in binary form, is 1001. 1001 has two zeroes and two ones; thus, 9 is a round number. The integer 26 is 11010 in binary; since it has two zeroes and three ones, it is not a round number.

Obviously, it takes cows a while to convert numbers to binary, so the winner takes a while to determine. Bessie wants to cheat and thinks she can do that if she knows how many "round numbers" are in a given range.

Help her by writing a program that tells how many round numbers appear in the inclusive range given by the input (1 ≤ Start < Finish ≤ 2,000,000,000).

Input

Line 1: Two space-separated integers, respectively Start and Finish.

Output

Line 1: A single integer that is the count of round numbers in the inclusive range Start.. Finish

Sample Input

2 12

Sample Output

6

  这道题的思路倒是出奇的好想,想了不一会就给我弄出来了,竟然还过了!

  既然是要我们存储的是二进制中0、1的数,那么,我们在solve()的时候,不如就存储二进制数即可,不再存储十进制,作出这样的改变即可!


#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#define lowbit(x) ( x&(-x) )
#define pi 3.141592653589793
#define e 2.718281828459045
#define INF 0x3f3f3f3f
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int maxN = 32;
int N, M, dp[maxN][maxN][maxN], digit[maxN];
int dfs(int pos, int num0, int num1, bool head, bool limit)
{
    if(pos <= 0) return num0 >= num1;
    if(head && !limit && dp[pos][num0][num1] != -1) return dp[pos][num0][num1];
    int ans = 0;
    int num = limit?digit[pos]:1;
    for(int i=0; i<=num; i++)
    {
        if(i == 0)
        {
            if(head) ans += dfs(pos - 1, num0 + 1, num1, true, limit && i == num);
            else ans += dfs(pos - 1, num0, num1, false, limit && i == num);
        }
        else ans += dfs(pos - 1, num0, num1 + 1, true, limit && i == num);
    }
    if(!limit) dp[pos][num0][num1] = ans;
    return ans;
}
int solve(int x)
{
    int len = 0;
    while(x)
    {
        digit[++len] = x & 1;
        x >>= 1;
    }
    return dfs(len, 0, 0, false, true);
}
int main()
{
    while(scanf("%d%d", &N, &M)!=EOF)
    {
        memset(dp, -1, sizeof(dp));
        printf("%d\n", solve(M) - solve(N-1));
    }
    return 0;
}

 

# -*- coding: utf-8 -*- from machine import Pin import onewire import ds18x20 import time # ====== 硬件配置 ====== ‌:ml-citation{ref="1,3" data="citationList"} # 5641AS数码管引脚定义(共阴型) # 位选引脚(控制哪一位显示) DIGITS = [Pin(5, Pin.OUT), # 第1位 Pin(18, Pin.OUT), # 第2位 Pin(19, Pin.OUT), # 第3位 Pin(21, Pin.OUT)] # 第4位 # 段选引脚(控制显示数字形状) SEGMENTS = [Pin(13, Pin.OUT), # a段 Pin(12, Pin.OUT), # b段 Pin(14, Pin.OUT), # c段 Pin(27, Pin.OUT), # d段 Pin(26, Pin.OUT), # e段 Pin(25, Pin.OUT), # f段 Pin(33, Pin.OUT), # g段 Pin(32, Pin.OUT)] # 小数点dp # 数字编码(共阴型,0表示点亮) NUMBERS = { 0: [0,0,0,0,0,0,1,1], # 0 1: [1,0,0,1,1,1,1,1], # 1 2: [0,0,1,0,0,1,0,1], # 2 3: [0,0,0,0,1,1,0,1], # 3 4: [1,0,0,1,1,0,0,1], # 4 5: [0,1,0,0,1,0,0,1], # 5 6: [0,1,0,0,0,0,0,1], # 6 7: [0,0,0,1,1,1,1,1], # 7 8: [0,0,0,0,0,0,0,1], # 8 9: [0,0,0,0,1,0,0,1], # 9 '-': [1,1,1,1,1,1,0,1], # 负号 'E': [0,1,1,0,0,0,0,1] # 错误标识 } # ====== DS18B20初始化 ====== ‌:ml-citation{ref="3" data="citationList"} ds_pin = Pin(15) # 温度传感器接GPIO15(示例引脚,可修改) ds_sensor = ds18x20.DS18X20(onewire.OneWire(ds_pin)) roms = ds_sensor.scan() # ====== 温度读取函数 ====== ‌:ml-citation{ref="3,4" data="citationList"} def read_temp(): try: ds_sensor.convert_temp() time.sleep_ms(750) # 等待温度转换 temp = ds_sensor.read_temp(roms) return round(temp, 1) except: return None # 传感器异常返回空值 # ====== 数码管显示函数 ====== ‌:ml-citation{ref="1,2" data="citationList"} def display_number(number, decimal_pos=-1): # 异常显示处理 if number is None: segments = NUMBERS['E'] + NUMBERS['E'][:-1] for i in range(4): DIGITS[i].value(0 if i==0 else 1) # 仅第一位显示E for seg, val in zip(SEGMENTS, segments): seg.value(val) time.sleep_ms(5) return # 数字分解处理 str_num = f"{abs(number):4.1f}".replace(' ','').zfill(4)
最新发布
03-09
### 使用MicroPython实现DS18B20温度传感器与7段数码管显示 #### 硬件准备 为了完成这一项目,需要以下组件: - DS18B20 温度传感器[^2] - 7段数码管显示器 - ESP32 开发板 (或其他支持MicroPython的微控制器) - 上拉电阻(通常为4.7KΩ),用于稳定1-Wire总线信号[^4] #### 软件环境配置 推荐使用 Thonny IDE 来编写和上传MicroPython程序至ESP32。确保已安装最新版本的Thonny并正确设置了目标设备。 #### 连接方式说明 对于DS18B20来说,它采用的是1-Wire通信协议,这意味着只需要一条数据线即可完成通讯操作;而7段数码管则可能依据具体型号不同采取不同的接口形式(如共阳极或共阴极),需按照实际产品手册进行连线设置。 #### Python代码实例 下面给出一段简单的MicroPython代码来读取来自DS18B20的数据并通过7段数码管展示出来: ```python from machine import Pin, I2C import onewire, ds18x20 import time from ht16k33_matrix import Matrix8x8 # 假设这里使用I2C驱动的HT16K33作为7段显示屏控制器 # 初始化OneWire总线以及DS18B20对象 dat = Pin(12) ow = onewire.OneWire(dat) ds = ds18x20.DS18X20(ow) roms = ds.scan() # 扫描网络上的所有器件 print('found devices:', roms) i2c = I2C(scl=Pin(5), sda=Pin(4)) display = Matrix8x8(i2c) while True: ds.convert_temp() time.sleep_ms(750) # 等待转换完成 for rom in roms: temp_celsius = round(ds.read_temp(rom)*10)/10 str_temperature = "{:.1f}".format(temp_celsius).zfill(5) display.clear() display.draw_text(str_temperature[:2], col_start=0) display.set_decimal_point(True, pos=1) display.draw_text(str_temperature[-2:], col_start=3) display.show() time.sleep(2) ``` 这段代码实现了每隔两秒钟更新一次当前检测到的摄氏度数值,并将其格式化后送入7段数码管上显示。注意这里的`ht16k33_matrix.py`文件是用来控制特定类型的LED矩阵/7段数码管库函数,在实际应用中应替换为你所使用的相应库。 #### 数据处理细节 当从DS18B20获得原始二进制表示之后,会先乘以一个小数因子再四舍五入得到最终的小数点精度结果[^5]。上述例子中的`round()`方法简化了这一步骤,直接得到了保留一位小数的结果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wuliwuliii

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值