题目描述
小明同学最近正在研究一些幂次的特性,比如 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;
}