要素の合計が偶数になる空でない部分集合の長さを求めるC++プログラム
n個の要素を持つ配列Aがあるとします。この中から要素の合計が偶数になるような空でない部分集合を見つけ、その長さを求める必要があります。条件を満たす部分集合が存在しない場合は、-1を返します。
例えば、入力が A = [1, 3, 7] の場合、[1, 3] の合計は4(偶数)となるため、出力は2になります。
解法の考え方
この問題は、配列内の要素の偶奇に着目することで非常にシンプルに解くことができます。
- 配列内に偶数が1つでも存在すれば、その要素単独で合計が偶数になるため、答えは 1
- すべての要素が奇数で、要素数が2以上であれば、任意の2つの奇数の合計は必ず偶数になるため、答えは 2
- 要素が1つだけで、かつそれが奇数の場合は、条件を満たす部分集合が存在しないため -1 を返す
アルゴリズムの手順
上記の考え方に基づき、以下の手順で処理を行います。
n := Aのサイズ
i := 0 で初期化し、i < n の間、i を1ずつ増やしながら繰り返す:
もし A[i] を 2 で割った余りが 0 の場合:
k := i + 1
もし n が 1 かつ k が 0 の場合:
-1 を返す
そうでなく、k が 0 以外の場合:
1 を返す
それ以外の場合:
2 を返す
実装例
理解を深めるために、以下のC++での実装例を見てみましょう。
#include <bits/stdc++.h>
using namespace std;
int solve(vector<int> A) {
long n = A.size(), k = 0;
for (long i = 0; i < n; i++) {
if (A[i] % 2 == 0) {
k = i + 1;
}
}
if (n == 1 & k == 0) {
return -1;
}
else if (k != 0) {
return 1;
}
else {
return 2;
}
}
int main() {
vector<int> A = { 1, 3, 7 };
cout << solve(A) << endl;
}
コードの解説
solve関数では、まずループを使って配列内に偶数が存在するかどうかを確認しています。変数kには、見つかった偶数の位置+1が記録され、kが0以外であれば「配列内に偶数が存在する」ことを意味します。
その後の条件分岐では、要素数が1かつ奇数のみの場合に-1を返し、偶数が存在する場合は1、すべて奇数で要素数が複数の場合は2を返します。
入力
{ 1, 3, 7 }
出力
2
この入力例では、配列内に偶数が存在しないため k は 0 のままです。しかし要素数が3(複数)なので、2つの奇数を選ぶことで合計を偶数にできるため、正しく2が出力されます。
-
C++で文字列の長さを求める方法:基本テクニックとstrlen()関数の使い方
C++における文字列とは、ヌル文字(\0)で終端される1次元の文字配列のことです。文字列の長さとは、このヌル文字より前に存在する文字数を指します。例えば、次のような文字列を考えてみましょう。char str[] = The sky is blue; 上記の文字列に含まれる文字数 = 15それでは、文字列の長さを求めるプログラムを見ていきましょう。例1:whileループを使って文字数をカウントする方法#include<iostream> using namespace std; int main() { char str[] = Apple; &n
-
Pythonで合計が0となる最長の部分リストの長さを求める方法
問題概要 1と−1という2つの値だけを含むリストが与えられたとき、要素の合計が0になる最長の部分リスト(連続する部分列)の長さを求めます。 例えば、入力が nums = [1, 1, -1, 1, 1, -1, 1, -1, 1, -1] の場合、出力は 8 になります。これは、最長の部分リストが [-1, 1, 1, -1, 1, -1, 1, -1] であり、その合計が0だからです。 解法のアプローチ:累積和と辞書 この問題は「累積和(プレフィックスサム)」を使うことで効率的に解けます。ある位置 i までの累積和が cs であるとき、同じ累積和の値が以前に位置 j で現れていれば、区間