第一周算法设计与分析:A : log2(N)

该博客介绍了如何在C++中计算log2N的下取整值,提供了三种不同的思路:使用math库的log和floor函数、循环逼近法以及pow函数。文章强调了精度问题和避免使用可能造成精度丢失的函数的重要性。

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

A : log2(N)

Time Limit: 1 Sec Memory Limit: 128 Mb Submitted: 205 Solved: 36

Description

给你一个数N,请你找出最大的的整数k,满足 2k ≤ N

Input

1 ≤ N ≤ 1019

Output

输出k并换行

Sample Input

6

Sample Output

2

Hint

注意精度问题

一、题目大意

输入一个数N,要求输出log2N(向下取整)

二、思路

1、储备知识:

a、四种取整函数
函数功能例子
floor ()向负无穷取整floor(2.5)=2,floor(-2.4)=-3
ceil()向正无穷取整ceil(2.5)=3,ceil(-2.4)=-2
trunc()向零取整trunc(2.5)=2,trunc(-2.4)=-2
round()四舍五入round(2.5)=3,round(-2.4)=-2
b.对数函数log()与指数函数pow()
函数功能例子
log(N)输出以e为底N的对数log(2.7)=0.993252
pow(a,n)输出底数为a的n次方pow(2,3)=8

注1:以上6种函数头文件:#include<math.h>
注2:数学上log26=log(6)/log(2)(要实现数学上的对数,可以用商来表示)
注3:如果可以尽量全都敲一遍,巩固记忆。

2、思路

思路A

将log2(N)转化成log(N)/log(2)
然后再向下取整。也就是使用floor函数
对应代码如下。

#include<iostream>
#include<math.h>
using namespace std;
int main()
{
    double n;
    cin>>n
    cout<<floor(log(n)/log(2))<<endl;
    return 0;
}

注:这个程序逻辑没有问题,但由于log()函数内参数为浮点数,取整的时候,可能出现精度丢失的问题。导致oj判错。

思路B

模拟逼近运算,将输入的数字num循环与20~264比较,当第一次出现2i>num时
则必然存在:num>=2i-1
在这里,抹去所有的浮点数,保证不会出现精度丢失的情况,算正统的解法

#include<iostream>
using namespace std;
int main()
{
    long long n,ans=1;
    cin>>n;
    for(int i=0;i<=64;i++)
    {
        if(n<ans){cout<<i-1<<endl;break;}//ans=2的i次方
        ans*=2;
    }
    return 0;
}
思路C

输入一个数n后,循环到0~64,当pow(2,i)大于n时输出i-1,原理等同于思路B

#include<iostream>
#include<math.h>
using namespace std;
int main()
{
    long long n;
    cin>>n;
    for(int i=0;i<=64;i++)
        if(n<pow(2,i)){cout<<i-1<<endl;break;}
    return 0;
}

思路A与思路C两个代码逻辑上没有问题,但由于log()与pow()内的参数为浮点数,在转化成整数的时候可能会出现精度丢失的问题,如果出题人恶意卡人是可能会wa的,所以在需要取整的时候幂函数和对数函数最好不用,而是全用整数。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

风吹落叶花飘荡

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

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

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

打赏作者

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

抵扣说明:

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

余额充值