题解 - 最接近

题目描述

小明同学最近正在研究一些幂次的特性,比如 32 = 9 和 43 = 64。

小花是小明的好朋友,她总是和小明一起学习,由于小花刚刚学习幂次,很多计算还不太熟练。她很好奇,对于任意给出的正整数 N,不超过 N 的最大的 2 的幂次方的数是多少?

例如:如果 N 等于 10,那么不超过 10 的最大的 2 的幂次方的整数就是 8,如果 N 是 100,那么不超过 100 的最大的 2 的幂次方的整数就是 64。小花希望你能帮助她解决这个问题。如果你能解决这个问题,就能和小花成为好朋友,小花希望朋友越多越好。

输入
输入只有一行一个正整数 N。

输出
输出只有一行一个正整数,表示不超过 N 的最大的 2 的幂次方的正整数。

样例输入 Copy
【输入样例 1】
10

【输入样例2】
100

样例输出 Copy
【输出样例1】
8

【输出样例2】
64
提示
【样例1解释】
不超过 10 的 2 的幂次方的正整数有 20 = 1,21 = 2,22 = 4,23 = 8,答案是 8。

【样例2解释】

不超过 100 的 2 的幂次方的正整数有 20 = 1,21 = 2,22 = 4,23 = 8,24 = 16,25 = 32,26 = 64,答案是 64。

【数据范围】
对于 100% 的数据,保证 1 ≤ N ≤ 1018。
在这里插入图片描述

题意

给出一个正整数n,输出不超过n的最大的 2 的幂次方的正整数

分析(方法一)

可以先对n取log2,得到最终结果的指数k,然后输出2的k次幂即可

代码

#include<bits/stdc++.h>
     
using namespace std;
    
typedef long long LL;
     
const int N = 100 + 10;
 
LL n;
 
int main(){
    ios::sync_with_stdio;
    cin.tie(0),cout.tie(0);
 
    cin >> n;

    int k = log2(n);
 
    cout << (LL)pow(2,k);
 
    return 0;
}

分析(方法二)

注意:1 ≤ N ≤ 10^18

n的值比较大,2的幂次方的值也比较大,所以要使用快速幂。

快速幂算法:

快速幂的核心思想是每一次都将指数分成两半,而相应的底数做平方运算。这能有效的将指数快速变小,需要执行的循环次数也大大减小。

快速幂基于以下事实:

①如果b是奇数,那么有ab=a*a(b-1)。

②如果b是偶数,那么有ab=a(b/2)*a^(b/2)。

ll qpow(ll a,ll b)
{
	ll ans=1;
	while(b)
	{
		if(b&1)
		{
			ans=ans*a;
			b--;
		}
		a=a*a;
		b/=2;
	}
	return ans;
}

代码:

#include <bits/stdc++.h>
#define MX 100000
typedef long long ll;
using namespace std;
ll qpow(ll a,ll b)
{
	ll ans=1;
	while(b)
	{
		if(b&1)
		{
			ans=ans*a;
			b--;
		}
		a=a*a;
		b/=2;
	}
	return ans;
}
int main()
{
    ll n;
    cin >> n;
    ll x,ans;
    for(int i = 1;;i++)
    {
        if(qpow(2,i) > n)
        {
            break;
        }
        else
        {
            x = i;
        }
    }
    ans = qpow(2,x);
    cout << ans << endl;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值