信息学奥赛复赛复习05-CSP-J2020-01优秀的拆分-对数函数、自然对数、以2为底的对数、幂函数、打表

news/2024/11/18 5:35:18/文章来源:https://www.cnblogs.com/myeln/p/18436207
PDF文档公众号回复关键字:20240927

1 2020 CSP-J 题目1 优秀的拆分

[题目描述]

一般来说,一个正整数可以拆分成若干个正整数的和

例如,1=1,10=1+2+3+4 等。对于正整数 n的一种特定拆分,我们称它为“优秀的”,当且仅当在这种拆分下,n被分解为了若干个不同的 2 的正整数次幂。注意,一个数 x 能被表示成 2 的正整数次幂,当且仅当 x 能通过正整数个 2 相乘在一起得到

例如,10=8+2=2^3 + 2^1 是一个优秀的拆分。但是,7=4+2+1=2^2 + 2^1 + 2^0 就不是一个优秀的拆分,因为 1 不是 2 的正整数次幂

现在,给定正整数 nn,你需要判断这个数的所有拆分中,是否存在优秀的拆分。若存在,请你给出具体的拆分方案

[输入格式]

输入只有一行,一个整数 n,代表需要判断的数

[输出格式]

如果这个数的所有拆分中,存在优秀的拆分。那么,你需要从大到小输出这个拆分中的每一个数,相邻两个数之间用一个空格隔开。可以证明,在规定了拆分数字的顺序后,该拆分方案是唯一的

若不存在优秀的拆分,输出 -1

[输入输出样例]

输入 #1

6

输出 #1

4 2

输入 #2

7

输出 #2

-1

说明/提示

样例 1 说明

6=4+2=2^2 + 2^1 是一个优秀的拆分。注意,6=2+2+2 不是一个优秀的拆分,因为拆分成的 3 个数不满足每个数互不相同

数据范围

对于 100% 的数据,1≤n≤10^7

2 相关知识点

1) 对数函数

C++提供了几个对数函数,可以用于计算不同底数的对数

自然对数

#include<bits/stdc++.h>
using namespace std;
/*自然对数 以e为底的对数 e的值约为2.718281828459045 
*/
int main(){double x= 3; double natural_log = log(x);cout<<natural_log<<endl;x= 2.718281828459045;natural_log = log(x);cout<<natural_log<<endl;return 0;
}
/*
输出
1.09861
1 
*/ 

10为底对数

#include<bits/stdc++.h>
using namespace std;
/*10为底的对数log10(100)=2 
*/
int main(){double x= 100; double _log10 = log10(x);cout<<_log10<<endl;x= 1000;_log10 = log10(x);cout<<_log10<<endl;return 0;
}
/*
输出
2
3
*/ 

2为底对数

#include<bits/stdc++.h>
using namespace std;
/*2为底的对数log2(16)=4 
*/
int main(){double x= 4; double _log2 = log2(x);cout<<_log2<<endl;x= 32;_log2 = log2(x);cout<<_log2<<endl;return 0;
}
/*
输出
2
5
*/ 

2) 幂函数

cmath pow

#include<iostream>
#include<cmath>
using namespace std;
/*pow函数该函数接收两个参数,base 为要取次方的数,exponent 为指数。返回结果为 base 的 exponent 次方 double x =pow(base,exponent);pow=(2,3)=8 
*/ 
int main(){int base=2;int exponent=3;double x=pow(base,exponent);cout<<x<<endl;exponent=4;x=pow(base,exponent);cout<<x<<endl;return 0;
}
/*
输出
8
16 
*/ 

3) 打表

在编程中,是指将重要或计算成本较高的结果预先计算好并存放在内存(表)中,以供后续操作快速引用。这种技术经常在解决算法问题时使用,尤其是面对那些具有固定规律性、重复运算量大的场景

提前计算2的幂次方,把符合范围的2的幂次方都提前计算存储数组中,后续可以直接使用

#include<bits/stdc++.h>
using namespace std;
int n,a[30],m=1;
/*计算所有小于10^7的数的2的幂存储的数组a
*/
int main(){for(int i=0;i<=22;i++){m*=2;a[22-i]=m;}for(int i=0;i<=22;i++){cout<<a[i]<<" ";} return 0;
}

输出a数组数据如下

3 思路分析

思路1

1 可以分解到最小2^1次幂的和,一定是偶数,所以奇数返回-1
2 通过log2(n)计算以2为底n的对数_log2,再通过2^(_log2)计算小于n的2的最大幂次数
3 每次去除并输出2的最大幂次数
4 剩余的n 重复步骤2
#include<bits/stdc++.h>
using namespace std;int main(){int n;cin>>n;if(n%2==1){//奇数返回-1cout<<-1;return 0;}while(n>1){int x=log2(n);//n的最大幂int base=pow(2,x);//n的最大幂次数 比如n=16 此时base为16 ,n=17此时base也为16 if(n>=base){//有2的幂次数n-=base;//去除本次输出的2的幂次数cout<<base<<" ";//输出此次2的幂次数}}
}

思路2

同思路1,计算2的幂次数使用打表法

提前计算所有小于等于n的最大幂次数,此时n的最大取整为10^7

#include<bits/stdc++.h>
using namespace std;int n,a[30],m=1;
int main(){for(int i=0;i<=22;i++){//打表提前计算所有小于10^7的幂次数,从大到小存储到a数组m*=2;a[22-i]=m;}cin>>n;if(n%2==1){//奇数返回-1cout<<"-1";return 0;}int idx=0;while(n>0 && idx<=23){//n都去除所有的2的幂次数if(n>=a[idx]){//包含此2的幂次数cout<<a[idx]<<" ";//输出此2的幂次数n=n-a[idx];//去除此2的幂次数}idx++;//找下一个2的幂次数}return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【蓝桥杯】“萌新首秀”全国高校新生编程排位赛2

1.世上有10种人 题目 世上有10种人 代码#include using namespace std; int main() {cout<<2;return 0; }2.01切换 题目 01切换 题目分析 直接判断字符串最后一个字符是0还是1就好了 代码#include using namespace std; int main() {string str;cin>>str;int l =…

Avalonia如何与通用主机Host集成实现MsDI

如果想在Aavalonia使用IOC,目前我能想到的就是使用Prism或者是MsDI,Prism内部使用的是DryIoc,这个和WPF几乎没什么差别,那如果我想使用微软实现的Ioc呢,也是可以的,实现方式其实很简单,就是使用IHost,其中依赖有两个库 Microsoft.Extensions.DependencyInjectionMicros…

软工第一次结对作业

这个作业属于哪个课程 https://edu.cnblogs.com/campus/fzu/SE2024这个作业要求在哪里 https://edu.cnblogs.com/campus/fzu/SE2024/homework/13261这个作业的目标 学习使用原型软件,辅助完成软件工程的前期任务学号 102201137结对成员学号 102201137 102201237原型链接 https…

C#爬取动态网页上的信息:B站主页

目录简介获取 HTML 文档解析 HTML 文档测试参考文章 简介 动态内容网站使用 JavaScript 脚本动态检索和渲染数据,爬取信息时需要模拟浏览器行为,否则获取到的源码基本是空的。爬取步骤如下:使用 Selenium 获取渲染后的 HTML 文档 使用 HtmlAgilityPack 解析 HTML 文档新建项…

基于 LangChain 的自动化测试用例的生成与执行

在前面的章节中,分别介绍了 Web、App、接口自动化测试用例的生成。但是在前文中实现的效果均为在控制台打印自动化测试的用例。用例需要手动粘贴,调整之后再执行。 那么其实这个手动粘贴、执行的过程,也是可以直接通过人工智能完成的。 应用价值通过人工智能代替人工操作的部…

数字孪生赋能BMS:开启电池管理新纪元

这几天,全世界的媒体几乎都在报道黎巴嫩爆炸案。原本此类地缘冲突的影响力是较为有限的,但是这次的事件不太一样:这次爆炸的,是几千个传呼机。这一事件迅速引发了全球范围内对于电子设备安全性的广泛关注:随着社会日益依赖各种高科技产品,从日常通信到交通出行,人们开始…

20240927

Fun is Counting 我们可以发现数组 \(a\) 必须是 \(x\) 或 \(x - 1\),然后分类讨论即可 #include <bits/stdc++.h>using namespace std;#define int long longconst int N = 1e6 + 5, mod = 998244353;int inv[N], f[N], g[N], t, n, a[N];int C(int a, int b) {if (a &l…

海报作业

海报主题:知识的力量设定: 目标:强调教育和知识对个人成长和社会发展的重要性 设计构思:1. 色彩:选择明亮且有活力的颜色,如蓝色和黄色,吸引眼球并传达积极的情绪。图像: 中心可以用一棵大树象征知识之树,树冠由书籍组成。 在树下,可以画出一群不同年龄和背景的人在学…

驱动导致win蓝屏(蓝屏code: 0x9f)

描述:在9月27日12点35分24秒系统发生蓝屏通过系统事件日志来看发现发现从发生蓝屏开始到下一次开机之间相隔4分钟左右 继续分析dump日志,此次蓝屏代码为0x9f通过dump日志来看,造成此次蓝屏的原因是驱动程序处于不一致或无效的电源状态。 In Windows Vista and later version…

wireshark抓不到TLS1.3数据包中证书的解决方案

近日工作中遇到需要分析使用TLS1.3协议进行通信的数据包的情况,但使用wireshark进行分析发现不能抓到服务端证书,感到诧异遂设法解决 这篇博客给出解决方案,和简单的原理分析近日工作中遇到需要分析使用TLS1.3协议进行通信的数据包的情况,但使用wireshark进行分析发现不能抓…

chrome实现点击书签, 新页面打开. (左键点击). 新标签打开书签 .

1. 我找了很多插件, 都没法实现点击书签, 自动新标签打开. 2. 但是我发现一款 chrome , 是可以实现的 https://www.ghxi.com/chrome.html 这是基于 chrome ++ 的增强版. 便携版和安装版使用起来没有任何区别 , 甚至重装系统依旧能用原来的数据. 如何开启新标签打开书签的功能, …