0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

AtCoderログ:0091 - ABC 215 B

Posted at

問題

問題文

正整数 $N$ が与えられるので、 $2^k \le N$ となる最大の整数 $k$ を求めてください。

制約

・$N$ は $1 \le N \le 10^{18}$ を満たす整数である

回答

回答1 (AC)

入力された $N$ に対し $2^1, 2,2,...$ を計算していき、はじめて $N < 2^i$ となる $i$ が見つかるまで繰り返すことにしました。コードは以下のようになりました。

abc215b-1.cpp
#include <bits/stdc++.h>
using namespace std;
 
int main() {
  int64_t n;
  cin >> n;

  int i = 0;
  int64_t p = 1;
  while ( p<=n ) {
    p *= 2;
    i++;
  }
  
  cout << i-1 << endl;
}

回答2 (WA)

設問の式の両辺の対数をとると $\log_2{2^k} \le \log_2{N}$ つまり $k \le \log_2{N}$ となるので、$\log_2$ の整数部分が求める $k$ の値となります。コードは以下のようになりますが、残念ながら WA となります。これは、$\log_2$ の計算精度が低いことが原因です。

abc215b-2.cpp
#include <bits/stdc++.h>
using namespace std;
 
int main() {
  int64_t n;
  cin >> n;
  
  cout << floor(log2(n)) << endl;
}

回答3 (AC)

回答2において、$\log_2$ への入力値を double にすると出力値も double となり、精度問題が解決できます。コードは以下のようになりました。

abc215b-3.cpp
#include <bits/stdc++.h>
using namespace std;
 
int main() {
  int64_t n;
  cin >> n;
  
  cout << floor(log2((long double)n)) << endl;
}

調べたこと

AtCoder の解説公式解説

3種類の回答が紹介され、最初の2つは回答1、回答3と同じ方針、3つ目は $N$ の2進展開を利用していました。

AtCoder の解説ユーザ解説

公式解説の3つ目の解法が、言語によってはライブラリにヨウイされているそうです。

リンク

前後の記事

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?