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

C++で指定金額ちょうどで商品を購入できるか判定する方法

ある数値 N が与えられたとします。ケーキ売り場では、ケーキが1つ40ルピー、ドーナツが1つ70ルピーで販売されています。このとき、所持金 N ルピーを使って、これらの商品をちょうど N ルピ―ぴったりで購入できるかどうかを判定します。

例えば、N = 110 の場合、40 + 70 = 110 となるため、出力は True(購入可能)になります。

解決のアプローチ

この問題は、深さ優先探索(DFS)を用いて解くことができます。基本的な考え方は以下の通りです。

  • 現在の合計金額 i を引数として DFS を実行します。
  • i が n より大きければ、その経路は失敗なので false を返します。
  • i が n と等しければ、ちょうどの金額に到達できたので true を返します。
  • そうでなければ、「i + 40(ケーキを買う)」と「i + 70(ドーナツを買う)」の2つの分岐を再帰的に試します。

アルゴリズムの手順

o := false
関数 dfs(i) を定義する
もし i > n ならば:
    return false
もし i == n ならば:
    return true
もし dfs(i + 40) が真ならば:
    return true
return dfs(i + 70)
main メソッドから以下を実行する
n := N
o := dfs(0)
return o

C++による実装例

それでは、実際の実装を見て理解を深めましょう。

#include <bits/stdc++.h>
using namespace std;
int n;
bool o = false;

bool dfs(int i) {
   if (i > n)
      return false;
   if (i == n)
      return true;
   if (dfs(i + 40))
      return true;
   return dfs(i + 70);
}
bool solve(int N) {
   n = N;
   o = dfs(0);
   return o;
}
int main(){
   int N = 110;
   cout << solve(N) << endl;
}

入力

110

出力

1

出力が 1(true)となっており、110ルピーちょうどでケーキ1つとドーナツ1つを購入できることが確認できます。

補足:計算量について

この DFS アプローチはシンプルですが、N が大きい場合は指数的な探索になる可能性があります。実際には「40a + 70b = N を満たす非負整数 a, b が存在するか」という問題に帰着できるため、N を10の倍数で割った余りや、線形方程式の整数解の存在チェックによって、O(1) 〜 O(N) 程度で効率的に判定することも可能です。

  1. 配列が高さnのBSTを表せるかどうかをC++で判定する方法

    サイズnの配列が与えられたとき、その配列が高さnの二分探索木(BST)を表すことができるかどうかを判定する問題について解説します。ここで「高さn」とは、根から葉までの最長パスがn個のノードで構成されることを意味し、つまり配列の各要素が木の各レベルに1つずつ対応することを指します。 問題の理解 BSTのルールに従って要素を挿入していくとき、配列の順序通りに挿入した結果、高さがちょうどn(要素数と同じ)になるかどうかを確認します。これは、配列の各要素が前の要素の左または右の子として挿入され、一度も同じレベルに複数のノードが配置されないことを意味します。 例として以下の2つの配列を考えます:

  2. Pythonで数値nがk個の素数の合計として表せるかどうかを判定するプログラム

    ある整数 n と個数 k が与えられたとき、「n を k 個の素数の合計として表すことができるかどうか」を判定する問題を考えてみましょう。例えば、入力が n = 30、k = 3 の場合、30 は「2 + 11 + 17」という3つの素数の合計で表せるため、出力は True になります。解法のアプローチこの問題を効率的に解くために、以下の手順に従います。n < 2×k の場合False を返す(最小の素数は2なので、k個の素数の合計の最小値は 2×k になるため)k > 2 の場合True を返す(任意の n ≥ 2k は k 個の素数の合計として必ず表現できることが知られているた