每天一道C语言编程(2^k进制数)

news2024/11/26 5:19:41

题目描述

设r是个2^k 进制数,并满足以下条件:
(1)r至少是个2位的2^k 进制数。
(2)作为2^k 进制数,除最后一位外,r的每一位严格小于它右边相邻的那一位。
(3)将r转换为2进制数q后,则q的总位数不超过w。
在这里,正整数k(1≤k≤9)和w(k〈w≤30000)是事先给定的。

问:满足上述条件的不同的r共有多少个?
我们再从另一角度作些解释:设S是长度为w 的01字符串(即字符串S由w个“0”或“1”组成),S对应于上述条件(3)中的q。将S从右起划分为若干个长度为k 的段,每段对应一位2^k进制的数,如果S至少可分成2段,则S所对应的二进制数又可以转换为上述的2^k 进制数r。
例:设k=3,w=7。则r是个八进制数(2^3=8)。由于w=7,长度为7的01字符串按3位一段分,可分为3段(即1,3,3,左边第一段只有一个二进制位),则满足条件的八进制数有:
2位数:高位为1:6个(即12,13,14,15,16,17),高位为2:5个,…,高位为6:1个(即67)。共6+5+…+1=21个
3位数:高位只能是1,第2位为2:5个(即123,124,125,126,127),第2位为3:4个,…,第2位为6:1个(即167)。共5+4+…+1=15个
所以,满足要求的r共有36个。

输入格式

只有1行,为两个正整数,用一个空格隔开:
k w

输出格式

1行,是一个正整数,为所求的计算结果,即满足条件的不同的r的个数(用十进制数表示),要求最高位不得为0,各数字之间不得插入数字以外的其他字符(例如空格、换行符、逗号等)。
(提示:作为结果的正整数可能很大,但不会超过200位)

样例输入

3  7

样例输出

36

解题思路(这一题脑袋转不过来,分析了好久,现在分享一下思路)

例k=3,w=7

则2^k=8,8进制数,在八进制数中列出 转换为2进制后的位数 小于7位数的数

例如8进制的12,转换为2进制后为1010

满足条件

1.r至少是个2位的2^k 进制数,12是2位的8进制数

2.12的每一位严格小于它右边相邻的那一位

3.转换为2进制后1010的位数4<7

对于8进制而言,2进制每3位数表示1个8进制数

  

得出结论: 

● 要小于7位2进制数的话,8进制数的位数只能是2位和3位,把这一思路推广一下

● 除了首位以外,其他位的取值范围是000~111((2^k)-1),即每一位可以取0~7

●首位为0的情况下,可取w/k位,并且w/k>=2

●所以首位为0的合法解有

∑ C(2^k-1,i)(2<=i<=w/k)

即对于k=3,w=7的情况下,可取C(7,2),就是在1~7中选两个数都是合法的,那么有21种可能。为什么这21种解刚好符合题目例子(再看一遍题目,题目有例子喔)中2位数的合法解(21)呢?(只有严格递增的排列才是合法的)

 

●这里用的是C进行组合,从7个中选择2个,不可能有重复的两位数,并且排列并没有像A(排列)一样,(1,2):第一位是1,第二位是2(2,1)都取,这里我们默认只取(1,2),即严格递增的排列

●为什么没有(3,4)呢,因为(2<=i<=w/k)有限制

以上讨论了二进制首位为0的情况,接下来讨论二进制首位为1的情况

●如果首位非0,那么8进制数就是三位数

●除了首位外,还有w/k位,要符合严格递增的要求,首位的取值范围只能是1~2^(w%k)-1,例如

余下1位,那么只有0,1这两种可能,减去0这种可能就只有1种可能了

●设首位取值为val

●则剩下w/k位取值范围为val+1~(2^k)-1

●也就是有(2^k)-1-(val+1)+1个数,即2^k-1-val,按照首位为0来讨论,其合法解有

∑ C(2^k-1-val,w/k)(1<=val<=2^(w % k)-1)

用代码得出8进制数的最高位数      2<=n<=8进制数的最高位数

int Level(int k,int w)
{
    int n=0;
    while(w>0)
    {
        w-=k;
        n++;
    }
    return n;
}

重要注 (反复思考一下)

对于高精运算的处理,在网上学习到了一个比较巧妙的方法避开了复杂的数组运算,也可以有效避免溢出,就是把上面那些组合数的运算都转换成了 C(2^k-1,i) —(+1-i)—- > C(2^k-i,i),即写C组合函数的时候不是计算C(2^k-1,i),而是计算C(2^k-i+i-1,i),即我们把(2^k-i,i)代入函数得到的是(2^k-1,i)的结果,那么C(2^k-1,i) <—(-1+i)—-  C(2^k-i,i),就需要将C(n,m)的计算,变为C(n+m-1,m)

long sump(int n, int m)        //公式为C(n+m-1)(m)
{
    int i;
    long sum = 1;
    for(i = 0 ; i < m ; i++)
        sum *= (n+m-1-i);
    for(i = 1 ; i <= m ; i++)
        sum /= i;
        return sum;
}

sump(2^k-i,i)----->n=2^k-i,m=i------->C(2^k-1,i)

sump(sump( 2^k- w/k - i , w/k)----->n=2^k-w/k-i m=w/k------>C(2^k-i-1,w/k)

反过来如果我们要计算C(2^k-i-1,w/k),公式位C(n+m-1)(m),也可以得到n=2^k-w/k-i

最终代码为

#include<stdio.h>
#include<math.h>
long sump(int n, int m)        //公式为C(n+m-1)(m)
{
    int i;
    long sum = 1;
    for(i = 0 ; i < m ; i++)
        sum *= (n+m-1-i);
    for(i = 1 ; i <= m ; i++)
        sum /= i;
        return sum;
}

int Level(int k,int w)//计算最高有几位数
{
    int n=0;
    while(w>0)
    {
        w-=k;
        n++;
    }
    return n;
}

int main()
{
    int k ,w ,i ;
    scanf("%d%d",&k,&w);
    int level = Level(k,w);
    int max = pow( 2.0 , k);//这里的max是去不到的,例如k=3,2^3=8,8进制每一位最高111,就是7
    int gao = pow( 2.0, w%k)-1;//最高位的数的最大值,即val,可以取0,就是w/k能整除的情况
    
    //开始计算,分两种情况,第一种,首位为0,那么后面x位数对应的个数符合c[max-1][x]
    long long sum = 0;
    
    //去掉最高位 level-1;且至少两位i=2开始
    for(i = 2 ; i <= level - 1;i++)
        sum += sump( max - i,i);

    //第二种情况,首位不是0,如果首位为n,解就有C[max-1-n][w/k]
    for( i = 1 ; i <= gao ; i++)
        sum += sump( max - w/k - i , w/k);
        printf("%d\n",sum);
    return 0;
}

如果上面计算有点糊涂,可以直接根据公式来:

#include<stdio.h>
#include<math.h>
long sump(int n, int m)        //公式为C(n)(m)
{
    int i;
    long sum = 1;
    for(i = 0 ; i < m ; i++)
        sum *= (n-i);
    for(i = 1 ; i <= m ; i++)
        sum /= i;
    return sum;
}

int Level(int k,int w)//计算最高有几位数
{
    int n=0;
    while(w>0)
    {
        w-=k;
        n++;
    }
    return n;
}

int main()
{
    int k ,w ,i ;
    scanf("%d%d",&k,&w);
    int level = Level(k,w);
    int max = pow( 2.0 , k);//这里的max是去不到的,例如k=3,2^3=8,8进制每一位最高111,就是7
    int gao = pow( 2.0, w%k)-1;//最高位的数的最大值,即val,可以取0,就是w/k能整除的情况
    
    //开始计算,分两种情况,第一种,首位为0,那么后面x位数对应的个数符合c[max-1][x]
    long long sum = 0;

    
    for(i=2;i<=w/k;i++)
        sum+=sump(max-1,i);
    
    //第二种情况,首位不是0,如果首位为n,解就有C[max-1-n][w/k]
    for( i = 1 ; i <= gao ; i++)
        sum += sump(max-1-i, w/k);
    printf("%d\n",sum);
    return 0;
}

这一题主要是理解题意+分析,代码编写方面难度不大

既然提到了进制,顺便复习一下进制转换

编写一个程序,不使用格式控制符 %x 的情况下,将十进制数转换为十六进制

代码如下

#include <stdio.h>
#include <stdbool.h>


int main(void)
{
    int decimal;
    bool negative = false;
    
    printf("输入一个十进制数: ");
    scanf("%d", &decimal); 
    
    // 判断并记录要转换的十进制数的正负号
    if(decimal < 0)
    {
        negative = true;
        decimal *= -1;
    }
    
    // 将该十进制数对16进行短除法,并将余数依次存入数组num中
    int i;
    char hex[10];
    for(i=0; i<10 && decimal!=0; i++)
    {
        switch(decimal % 16)
        {
        case 0 ... 9:
            hex[i] = decimal%16 + '0';
            break;
        case 10 ... 15:
            hex[i] = decimal%16 - 10 + 'A';
            break;
        }
        decimal /= 16;
    }

    
    printf("转换成十六进制为: %c0x", negative?'-':' ');
    
    // 将数组num中的数字倒序输出
    int j;
    for(j=i-1; j>=0; j--)
    {
        printf("%c", hex[j]);
    }
    
    printf("\n");
    return 0;
}

结果展示

 今天的每日一题就到这里,如果有任何问题,请大佬们不吝赐教!💖💖💖

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/794362.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

NoSQL之 Redis 部署,配置与优化

文章目录 NoSQL之 Redis配置与优化一.关系数据库与非关系型数据库1.关系型数据库2.非关系型数据库3.关系型数据库和非关系型数据库区别4.非关系型数据库产生背景 二.Redis简介1.了解Redis2.Redis 具有以下几个优点3.Redis为何这么快 三.Redis 安装及应用1.Redis 安装部署2.Redi…

linux网卡命名规则与修改方法

一.前言&#xff1a; 在早期的的操作系统中例如fedora13或者ubuntu15之前网卡命名的方式为eth0&#xff0c;eth1&#xff0c;eth2&#xff0c;属于biosdevname 命名规范。当然这是针对intel网卡的命名规则&#xff0c;对于realtek类型的网卡会命名为ens33。但是这个编号往往不一…

数据库运维——MySQL主从复制

1.理解MySQL主从复制原理。 2.完成MySQL主从复制。 一、MySQL主从复制原理 MySQL主从复制是指将一个MySQL数据库服务器&#xff08;称为主服务器&#xff09;上的数据复制到其他MySQL数据库服务器&#xff08;称为从服务器&#xff09;的过程。它的原理如下&#xff1a; 主服…

如何利用OpenAI的函数调用特性

如何利用OpenAI的函数调用特性 函数调用能实现哪些功能&#xff1f; 简单来说&#xff0c;函数调用功能可以助你在请求方法时构建结构化的数据。因为生成模型的特性&#xff0c;它产生的数据往往是无结构的&#xff0c;即使在提示(prompt)中指定了输出格式&#xff0c;但实际…

3-Linux实操

Linux实践操作 开关机、重启、用户登陆注销关机&重启用户登陆和注销 用户管理添加用户修改用户密码删除用户查询用户信息切换用户查看当前用户用户组的添加和删除用户和组相关文件 实用指令指定运行级别init 命令帮助指令文件目录类时间日期类搜索查找类&#x1f50d;压缩和…

新能源汽车直流充电桩和交流充电桩的区别

直流充电桩和交流充电桩的区别 你是否曾经想过&#xff0c;为什么有的电动汽车可以在半小时内充满电&#xff0c;而有的却需要几个小时?其实&#xff0c;这都取决于它们所使用的充电桩的不同。那么&#xff0c;直流充电桩和交流充电桩到底有哪些区别呢? 首先&#xff0c;工作…

网络变压器配套使用的网口连接器的选型注意事项及选购关注要点

Hqst盈盛&#xff08;华强盛&#xff09;电子导读&#xff1a;采购人员在网口连接器选型中如何选用到合适的产品&#xff0c;选用时要注意到哪些事项&#xff0c;这节将结合网口连接器实物和大家一起探讨&#xff0c;希望对大家有些帮助。 我们可以通过对下面五个方面的详细了解…

网工内推 | 售前、售后工程师,IE认证优先

01 广州佳杰科技有限公司 招聘岗位&#xff1a;IT售前工程师 职责描述&#xff1a; 1、负责所在区域 IT 产品的售前技术支持工作,包括客户交流、方案编写、配置报价、投标应标、测试、赋能等; 2、与厂商相关人员建立和保持良好的关系,相互配合,提高项目成功率和厂商满意度; 3、…

每日一题——链表中倒数最后k个结点

题目 输入一个长度为 n 的链表&#xff0c;设链表中的元素的值为 ai &#xff0c;返回该链表中倒数第k个节点。 如果该链表长度小于k&#xff0c;请返回一个长度为 0 的链表。 数据范围&#xff1a;0≤n≤$105&#xff0c;0≤ai≤109&#xff0c;0≤k≤109 要求&#xff1a;…

MongoDB索引结构,到底是B-Tree还是B+Tree,请看这里!!

起因 网上关于MongoDB的索引结构到底是b树&#xff0c;还是b树的争论有很多&#xff0c;无法统一结论。 由来 MongoDB从3.2版本开始默认采用了WiredTiger存储引擎&#xff0c;网上很多说法是此引擎是BTree的索引结构&#xff0c;甚至有图有真相。但是认为MongoDB一直是B-Tre…

Docker compose(容器编排)

Docker compose&#xff08;容器编排&#xff09; 一、安装Docker compose 1.安装Docker compose Docker Compose 环境安装 Docker Compose 是 Docker 的独立产品&#xff0c;因此需要安装 Docker 之后在单独安装 Docker Compose#下载 curl -L https://github.com/docker/co…

htmlCSS-----定位

目录 前言 定位 分类和取值 定位的取值 1.相对定位 2.绝对位置 元素居中操作 3.固定定位 前言 今天我们来学习html&CSS中的元素的定位&#xff0c;通过元素的定位我们可以去更好的将盒子放到我们想要的位置&#xff0c;下面就一起来看看吧&#xff01; 定位 定位posi…

HR SaaS厂商,进入决赛圈

在愈发需要降本增效的节点&#xff0c;数字化的价值也更在被越来越多的企业重新审视&#xff0c;这种重视不再是之前或有或无的可选项&#xff0c;而是基于真正人效比维度的必选项 作者|斗斗 编辑|皮爷 出品|产业家 SaaS行业&#xff0c;正在发生一些微妙的变化。 以HR …

如何提高小程序UV?实用策略助你增加用户规模和活跃度

摘要&#xff1a;小程序的UV&#xff08;Unique Visitors&#xff09;是衡量用户规模和活跃度的重要指标&#xff0c;对于开发者和运营者来说具有重要意义。本文将分享一些实用策略&#xff0c;帮助你提高小程序的UV&#xff0c;增加用户规模和活跃度。从优化推广渠道、提升用户…

css实现鼠标滑动左下角弹框带动画效果

代码 <div classNamekuang></div> css代码 .kuang {height: 500px;width: 400px;// background-color: #fff;position: absolute;z-index: 10;bottom: 0;transform: translateX(-390px)}.kuang:hover {animation: myanimation 3s linear 1;animation-fill-mode:f…

LT9211C 是一款MIPI/RGB/2PORT LVDS互转的芯片

LT9211C 1.描述&#xff1a; Lontium LT9211C是一个高性能转换器&#xff0c;可以在MIPI DSI/CSI-2/双端口LVDS和TTL之间相互转换&#xff0c;除了24位TTL到24位TTL&#xff0c;并且不推荐同步和DE的2端口10位LVDS和24位TTL之间的转换。LT9211C反序列化输入的MIPI/LVDS/TTL视…

认识雪花id

首先,个人理解,雪花id不是全球的,它只能保证一个分布式服务的范围内的ID是不重复的. 一.SnowFlake 雪花算法 SnowFlake 中文意思为雪花&#xff0c;故称为雪花算法。最早是 Twitter 公司在其内部用于分布式环境下生成唯一 ID。在2014年开源 scala 语言版本。 雪花算法的原理…

项目经理好,还是产品经理好?

我首先介绍一下产品经理和项目经理的区别&#xff0c;然后再说一下产品经理和项目经理的薪资差距&#xff0c;然后你自己决定做产品经理还是项目经理。 1、产品经理和项目经理的区别&#xff1a; 产品经理和项目经理的不同之处在于&#xff0c;产品经理注重思考&#xff0c;关…

操作系统18:磁盘I/O速度、磁盘可靠性、数据一致性

目录 1、提高磁盘I/O速度的途径 &#xff08;1&#xff09;磁盘高速缓存(Disk Cache) 1.1 - 数据交付(Data Delivery)方式 1.2 - 置换算法 1.3 - 周期性地写回磁盘 &#xff08;2&#xff09;提高磁盘I/O速度的其它方法 2.1 - 提前读 2.2 - 延迟写 2.3 - 优化物理块的…

存储简单了解

存储目前常用的有磁盘&#xff08;磁性存储器&#xff09;和固态硬盘&#xff08;半导体存储器&#xff09; 磁盘由盘片&#xff0c;磁头和移动磁头的机械装置组成。磁盘从空间结构上分为扇区和磁道&#xff0c;每个扇区存储大小一致。 固态硬盘由多个闪存芯片组成&#xff0c;…