C++
 Computer >> コンピューター >  >> プログラミング >> C++

C++で3人チームの最大結成数をカウントする方法【アルゴリズムと実装例】

問題概要

n 個の要素を持つ配列 A があるとします。これは n 個の学生グループを表しています。各グループは次のいずれかのタイプです。

  • 誰とでもチームを組むことができる 1 人の学生
  • 必ず同じチームでコードを書きたい 2 人の学生

しかし、メンターはちょうど 3 人ずつのチームを結成することにしました。ここで求めたいのは、メンターが結成できる 3 人チームの最大数です。なお、2 人グループについては「2 人そろって参加する」か「2 人そろって不参加」のどちらかしか選べず、参加する場合は必ず同じチームに所属しなければなりません。

たとえば、入力が A = [2, 2, 2, 1, 1, 1, 1] の場合、出力は 3 になります。メンターは次のようなチーム編成が可能だからです。

  • [1 番目の 2 人グループ + 7 番目の 1 人グループ]
  • [2 番目の 2 人グループ + 6 番目の 1 人グループ]
  • [3 番目の 2 人グループ + 4 番目の 1 人グループ]

解き方の手順

この問題は、次の手順で効率的に解くことができます。

  1. 配列を走査し、1 人グループの総数を p、2 人グループの総数を q としてカウントします。
  2. p > q の場合: すべての 2 人グループ(q 個)に 1 人ずつ加えて q チームを作り、余った 1 人グループ(p − q 人)だけでさらに (p − q) / 3 チームを編成できます。したがって答えは q + (p - q) / 3 となります。
  3. p ≤ q の場合: 各 1 人グループを異なる 2 人グループに振り分けるのが最適であり、これ以上チームを増やせないため、答えは p となります。

この擬似コードで処理の流れを確認してみましょう。

p := 0
q := 0
x := 配列Aのサイズ
i := 0 から x 未満の間、1 ずつ増やしながら繰り返す:
    a := A[i]
    もし a が 1 と等しいならば:
        p := p + 1
    そうでなければ:
        q := q + 1
もし p > q ならば:
    return q + (p - q) / 3
そうでなければ(p <= q のとき):
    return p

C++ での実装例

理解を深めるために、実際の C++ コードを見てみましょう。計算量は O(n) と非常に効率的です。

#include <bits/stdc++.h>
using namespace std;
int solve(vector<int> A){
   int p = 0, q = 0;
   int x = A.size();
   for (int i = 0; i < x; i++){
      int a = A[i];
      if (a == 1){
         p = p + 1;
      }
      else{
         q = q + 1;
      }
   }
   if (p > q){
      return q + (p - q) / 3;
   }
   else if (p < q){
      return p;
   }
   else{
      return p;
   }
}
int main(){
   vector<int> A = { 2, 2, 2, 1, 1, 1, 1 };
   cout << solve(A) << endl;
}

入力

{ 2, 2, 2, 1, 1, 1, 1 }

出力

3
  1. 【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の累乗にできる

  2. 【C++解説】最大k回の加算操作で等しくできる要素数の最大化アルゴリズム

    この問題では、与えられた配列に対して、各要素を合計で最大k回まで増加(+1)できるという条件下で、等しい値にできる要素の最大個数を求めます。 まず、具体例を使って何をすべきか確認してみましょう。 入力例1 a[] = {1, 3, 8}, k = 4 出力例1 2 説明 この例では、要素「1」を3回、「3」を4回(計7回…と見せかけて、実際は各要素への加算回数の合計がk以内に収まるように調整)インクリメントすることで、2つの「4」を作り出せます。結果として配列は a[] = {4, 4, 8} となり、答えは 2 です。 入力例2 arr = {2, 5, 9}, k = 2 出力例2 0 こ