CF53B题解
一道水题。
首先要先枚举出 $2^a$ 最大可以是多少,而如果长是 $2^a$,则宽是 $\min(w,2^a \div 4)$ 反之,长也是一样。
所以就只是这样是不是太无聊了?
今天我来介绍一种优化幂次方的方法:
快速幂
神犇们可以直接跳过
众所周知,直接求解 $a^b$ 是 $O(n)$ 的时间复杂度,代码如下:
#include<bits/stdc++.h>
using namespace std;
int main(){
int a,b,ans=1;
cin>>a>>b;
for(int i=1;i<=b;i++){
ans*=a;
}
cout<<ans;
return 0;
}
但是这样也太慢了吧!
所以我们就可以使用快速幂来优化。(注:为美观起见,以下所有除法均视为向下取整)
设求 $a^b$
-
如果 $b$ 是奇数,则 $a^b = a^{b\div2}\times a^{b\div2} \times a$
-
如果 $b$ 是偶数,则 $a^b=a^{b/2}\times a^{b/2}$
-
如果 $b$ 是 $0$,答案就是 $1$
那么我们可以使用递归来解决这个问题,代码如下:
int ksm(int a,int b){
if(b==0){
return 1;
}
int t=ksm(a,b/2);
if(b&1){
return t*t*a;
}
else{
return t*t;
}
}
代码
#include<bits/stdc++.h>
using namespace std;
#define int long long//注意要开long long
int h,w;
int ksm(int a,int b){//快速幂
if(b==0){
return 1;
}
int t=ksm(a,b/2);
if(b&1){
return t*t*a;
}
else{
return t*t;
}
}
signed main(){
cin>>h>>w;
int a=1;
while(ksm(2,a)<=h&&ksm(2,a)<=w){
a=ksm(2,a);//求出最大的a
}
int x=min(h,a*5/4);
int y=min(w,a*5/4);
if(x<y){
cout<<a<<" "<<x;
}
else{
cout<<y<<" "<<a;
}
return 0;
}