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

目標値xにちょうど到達するサイコロの投げ回数を求めるC++コード


問題の概要

整数 x が与えられているとします。手元にあるのは、各面に 2 から 7 までの数字が書かれた 6 面体サイコロです。目標は、サイコロを振って出た目の合計をちょうど x にすることです。

ここでポイントになるのは、振る回数は自由という点です。合計がちょうど x になるような投擲回数が 1 つ分かれば十分で、その結果が出る確率が 0 でない限り、幸運にも実際にその通りの出目を得られるものとします。つまり、条件を満たす任意の回数を 1 つ答えればよいのです。

考え方

この問題を解くカギは、サイコロの最小の出目が 2 であることに着目することです。

  • x が偶数の場合: 毎回 2 を出せばよく、必要な回数は x / 2 回です。
  • x が奇数の場合: 1 回だけ 3 を出し、残りはすべて 2 にすれば、⌊x / 2⌋ 回で合計がちょうど x になります。

どちらの場合も答えは「x を 2 で割った値の小数点以下を切り捨てたもの」、すなわち ⌊x / 2⌋ となります。

具体例

入力が x = 100 の場合を考えてみましょう。たとえば「2 を 11 回、3 を 6 回、6 を 10 回」と出せば合計は 22 + 18 + 60 = 100 となり、27 回の投擲で目標を達成できます。ただしこれは一例にすぎず、正解となる回数は複数存在します。最もシンプルなのが毎回 2 を出す方法で、本記事で紹介する解法はこの発想に基づいて ⌊x / 2⌋ = 50 を出力します。

解法の手順

この問題は、次のわずか 1 ステップで解けます。

return floor of (x / 2)

C++ 実装例

理解を深めるために、実際のコードを見てみましょう。C++ では int 型同士の除算で小数点以下が自動的に切り捨てられるため、単に x / 2 を返すだけで ⌊x / 2⌋ が得られます。

#include<bits/stdc++.h>
using namespace std;
int solve(int x){
    return x/2;
}
int main(){
    int x = 100;
    cout << solve(x) << endl;
}

入力

100

出力

50

出力の 50 は「毎回 2 を出したときの投擲回数」です。2 × 50 = 100 となり、ちょうど目標に到達できることが確認できます。

まとめ

最小の出目が 2 であることを利用すれば、答えが ⌊x / 2⌋ に一致することを示せました。計算量は O(1) と非常に効率的で、x が偶数ならすべて 2、奇数なら 1 回だけ 3 を出すことで必ず達成できます。


  1. 【C++】長方形に含まれる正方形の総数を求めるアルゴリズムと実装

    縦の長さL、横の幅B(L≥B)の長方形が与えられたとします。この記事では、L×Bの長方形の中にいくつの正方形が含まれているかを効率的に求める方法を解説します。 上の図は3×2の長方形の例です。この長方形には、2×2の正方形が2個、1×1の正方形が6個含まれています。 合計:6+2=8個 規則性を見つける まず、正方形だけで構成されたB×Bの図形について考えてみましょう。 サイズL×Bの長方形には、必ずL×B個の1×1の正方形が含まれます。 含まれる最大の正方形のサイズはB×Bです。 L=B=1の場合:正方形の数=1 L=B=2の場合:正方形の数=1+4=5(2×2が1個、1×1が4個) L

  2. Pythonでサイコロの出目の合計がターゲットと一致する組み合わせの数を求める

    d個のサイコロがあり、それぞれのサイコロには1からfまでの数字が書かれた面があるとします。このとき、出た目の合計がターゲットの値と一致するような振り方(全 fd 通りのうち)の数を、10^9 + 7 で割った余りとして求めます。 例えば、d = 2、f = 6、target = 7 の場合、答えは6になります。6面のサイコロ2つを振って合計が7になる組み合わせは、「1+6」「2+5」「3+4」「4+3」「5+2」「6+1」の6通り存在するためです。 解法のアプローチ この問題は動的計画法(DP)を使うことで効率的に解けます。手順は以下の通りです。 m := 10^9 + 7(剰余を取るため