【C++】1を加えることで2の累乗にできる数の個数を求める方法
問題概要
正の整数からなる配列が与えられます。求めたいのは、各要素に対して最大1回だけ「1を加える」という操作を行うことで、2の累乗にすることができる数の個数です。
判定には log2(i) を活用します。2の累乗の対数は必ず整数になるため、floor(log2(i)) と ceil(log2(i)) が一致すれば、その数は2の累乗だと判断できます。この性質を使って、「そのまま2の累乗であるか」「1を加えれば2の累乗になるか」をチェックし、条件を満たすたびにカウントを増やしていきます。
具体例で確認してみましょう。
入出力例
入力: arr[] = {1, 3, 2, 5, 6}
出力: 2の累乗にできる数の個数: 3
説明: 1+1=2(=21)、3+1=4(=22)、そして 2 はもともと 21 なので計3個が該当します。残りの要素は 5+1=6、6+1=7 となり、どちらも2の累乗にはなりません。
入力: arr[] = {2, 4, 8, 16}
出力: 2の累乗にできる数の個数: 4
説明: 4つの要素はすべて、すでに2の累乗です。
アルゴリズムの流れ
- ランダムな正の整数で初期化された整数配列 arr[] を用意します。
- 関数 powofTwo(int arr[], int n) は配列とその長さを引数に受け取り、2の累乗であるか、または操作によって2の累乗にできる数の個数を返します。
- カウントの初期値を 0 とします。
- i = 0 から i < n まで配列を先頭から順に走査します。
- 各要素について、floor(log2(arr[i])) == ceil(log2(arr[i]))(arr[i] 自体が2の累乗の場合)または floor(log2(arr[i]+1)) == ceil(log2(arr[i]+1))(arr[i] に1を加えると2の累乗になる場合)が成立するかを確認し、いずれかが真であればカウントを1増やします。
- 最終的な結果として count を返します。
C++による実装例
#include <bits/stdc++.h>
#include <math.h>
using namespace std;
int powofTwo(int arr[],int n){
int count=0;
for(int i=0;i<n;i++){
if( floor(log2(arr[i])) == ceil(log2(arr[i])) )
{ count++; }
else{
++arr[i];
if( floor(log2(arr[i])) == ceil(log2(arr[i])) )
{ count++; }
}
}
return count;
}
int main(){
int Arr[]={ 5,6,9,3,1 };
int len=sizeof(Arr)/sizeof(Arr[0]);
cout<<endl<<"Count of numbers with power of 2 possible: "<<powofTwo(Arr,len);
return 0;
}
実行結果
上記のコードを実行すると、次のような出力が得られます。
Count of numbers with power of 2 possible: 2
この例では、{5, 6, 9, 3, 1} のうち、9+1=10、5+1=6、6+1=7 では2の累乗になりませんが、3+1=4(=22)と 1+1=2(=21)が該当するため、答えは 2 となります。この手法の計算量は O(n) であり、配列を一度走査するだけで判定が完了するため、非常に効率的です。
-
C++で「スーパー回文」(回文の2乗が回文になる数)を数える方法
本記事では、回文の2乗が回文となる数(スーパー回文)の個数を求めるC++プログラムについて詳しく解説します。スーパー回文とは?まず、2つの整数 L と R が与えられます。私たちのタスクは、この範囲 [L, R] 内に存在するスーパー回文の個数を求めることです。スーパー回文とは、その数自身が回文であり、さらにその2乗も回文となっている特別な数のことです。例えば、「3」は回文であり、その2乗「9」も回文なので、3はスーパー回文です。アルゴリズムの考え方範囲内のすべての数を1つずつ調べるのは非効率です。そこで、次のようなアプローチを取ります。回文を生成してから判定することで、探索範囲を大幅に絞り込
-
C++で配列要素の加減算により指定範囲内の最大値を求める方法
問題文整数の配列、初期値となる数値、および最大値が与えられます。配列の要素を先頭から順に走査し、各要素について「現在の結果に加算する」か「減算する」かを選択します。ただし、どの時点でも結果は 0 以上かつ最大値以下でなければなりません。インデックス 0 の処理では、与えられた数値を初期結果として扱います。条件を満たす答えが存在しない場合は -1 を出力します。例として、arr[] = {3, 10, 6, 4, 5}、number = 1、最大値 = 15 が与えられた場合、次の順序で加算・減算を行うと出力は 9 になります。1 + 3 + 10 - 6 - 4 + 5アルゴリズムこの問題は再