C++で最大K回のスワップにより作成できる最大の数を求める方法
この問題では、2つの整数値 n と k が与えられ、最大K回までのスワップ(入れ替え)によって作成できる最大の数 を求めることが課題となります。
問題の概要
ここで必要なのは、与えられた数字の桁を最大k回まで入れ替えたときに作れる、最も大きな数を計算することです。
例で理解してみましょう
- 入力: n = 538, k = 1
- 出力: 835
説明: 「8」と「5」を入れ替えることで、最大の数「835」が得られます。
解法アプローチ
この問題を解くには、数字の桁を最大k回入れ替えながら、その都度できる数が最大であるかどうかを確認する必要があります。
基本的な考え方は以下の通りです。
- 数の中から最大の桁を見つけます。
- その最大の桁を先頭のインデックスと入れ替えます。
- 同様の手順を、残りのk回分の入れ替えに対して繰り返します。
この処理は再帰的に実装すると、すべての組み合わせを網羅的に探索でき、確実に最大値を見つけられます。
解法の動作を示すプログラム
サンプルコード
#include <bits/stdc++.h>
using namespace std;
void calcMaxNumAfterSwap(string number, int k, string& maxString, int n){
if (k == 0)
return;
for (int i = 0; i < n - 1; i++) {
for (int j = i + 1; j < n; j++) {
if (number[i] < number[j]) {
swap(number[i], number[j]);
if (number.compare(maxString) > 0)
maxString = number;
calcMaxNumAfterSwap(number, k - 1, maxString, n);
swap(number[i], number[j]);
}
}
}
}
int main(){
string str = "15263";
int k = 3;
int size = str.length();
string maxString = str;
calcMaxNumAfterSwap(str, k, maxString, size);
cout<<"The maximum number created after "<<k<<" swaps is "<<maxString;
return 0;
}出力
The maximum number created after 3 swaps is 65321
コードの解説
このプログラムでは、関数 calcMaxNumAfterSwap が再帰的に呼び出され、可能なすべての桁の入れ替えパターンを試します。各ステップで現在の数がこれまでの最大値 maxString より大きければ、それを新しい最大値として記録します。バックトラッキングのために、再帰呼び出しの後に入れ替えを元に戻している点がポイントです。
上記の例では、文字列「15263」に対して3回のスワップを行うことで、最大の数「65321」が作成されます。
-
C++で配列から4つの要素を選んだ最大積を求める方法
n個の整数が格納された配列が与えられたとき、その中から4つの要素を選んで作れる積(クアドラプル)の最大値を求める問題について解説します。例えば、配列が [3, 5, 20, 6, 10] の場合、最大積は 6000 となり、このとき選ばれる4つの要素は 10, 5, 6, 20 です。解法のアプローチこの問題は、配列をソートすることで効率的に解くことができます。最大積の候補として考えられるのは以下の3パターンだけです。配列を昇順にソートするx = 最後の4要素(最も大きい4つ)の積とするy = 最初の4要素(最も小さい4つ)の積とするz = 最初の2要素と最後の2要素の積とするx、y、z のう
-
【C++】2つの頂点間の辺素パス(エッジディスジョイントパス)の最大数を求める方法
この記事では、C++を使って、グラフ上の2つの頂点(始点と終点)の間に存在する辺素パスの最大数を求めるプログラムを紹介します。辺素パスとは、互いに同じ辺(エッジ)を1つも共有しない複数のパスのことであり、その最大本数は2頂点間の最大フロー(最大流)と一致するという重要な性質を持っています。 アルゴリズム 開始 関数 bfs():残余グラフ上で始点 s から終点 t への経路が 存在する場合に true を返す。 (これはグラフにまだ流せるフローが残っていることを示す) 終了 開始 関数 findDisPath():与えられたグラフの最大フローを返す。 A) フローを 0