C++で解く!3番目のプレイヤーのサイコロが最大の目となる確率の求め方
3人のプレイヤーA、B、Cが順番にサイコロを投げる場面を考えます。本記事では、Cが投げた目がAとBの両方よりも大きくなる確率を求める方法を解説します。
3番目のサイコロの目が、それまでの2つの目より大きくなる確率を計算するには、この条件をしっかり意識することが重要です。
例えば、Aが「2」を出し、Bが「3」を出したとしましょう。このときCがこれらより大きい値を出せるのは「4」「5」「6」の3通りだけです。したがって、確率は3/6=1/2となります。
入出力例
入力:
A = 3, B = 5
出力:
1/6
説明: 3と5の両方よりも大きい値は「6」のみであるため、確率は1/6となります。
入力:
A = 2, B = 4
出力:
1/3
説明: 2と4の両方よりも大きい値は「5」と「6」の2つであり、確率は2/6です。これを約分すると1/3になります。
問題を解くためのアプローチ
- AとBの値のうち最大値を求めます。
- 6からその最大値を引き、結果と6の最大公約数(GCD)を計算します。
- GCDで割って約分した結果を返します。
アルゴリズム
開始
ステップ1 → 3番目のサイコロでより大きな値が出る確率を求める関数
void probab_third(int a, int b)
int c = 6 - max(a, b) を宣言
int GCD = __gcd(c, 6) を宣言
結果を出力
ステップ2 → main() 内での処理
int a = 2, b = 2 を宣言
probab_third(a, b) を呼び出す
終了実装コード(C++)
#include <bits/stdc++.h>
using namespace std;
// 3番目のサイコロでより大きな値が出る確率を求める関数
void probab_third(int a, int b){
int c = 6 - max(a, b);
int GCD = __gcd(c, 6);
cout<<"3番目のサイコロでより大きな値が出る確率 : " <<c / GCD << "/" << 6 / GCD;
}
int main(){
int a = 2, b = 2;
probab_third(a, b);
return 0;
}実行結果
上記のコードを実行すると、以下の出力が得られます。
3番目のサイコロでより大きな値が出る確率 : 2/3
このように、最大公約数を利用して分数を約分することで、常に最もシンプルな形で確率を表現できます。サイコロのような離散的な確率問題では、この手法が非常に有効です。
-
C++で3番目に大きい数を求める方法|O(n)の線形時間アルゴリズム
空でない整数配列が与えられたとき、その中の3番目に大きい数(第3最大値)を求める問題を考えます。第3最大値が存在しない場合は、代わりに最大値を返します。ここでのポイントは、線形時間 O(n) で解く必要があるという点です。 例えば、入力が [5,3,8,9,1,4,6,2] の場合、出力は 6 となります。 解法のアプローチ この問題は、上位3つの値を常に追跡する変数を用意すれば、配列を一度走査するだけで解けます。手順は以下の通りです。 3つのポインタ変数 a、b、c を NULL で初期化します。それぞれ最大値・2番目・3番目に大きい値へのポインタとして機能します。 i := 0 から配
-
C++で解くチェス盤上のナイトが盤内に残る確率の求め方
問題概要 N×Nのチェス盤があるとします。ナイトはr行c列目のマスからスタートし、ちょうどK回の移動を試みます。行と列は0始まりのインデックスで表されるため、左上のマスは(0, 0)、右下のマスは(N-1, N-1)となります。 ナイトは1つのマスから8種類の異なるマスへ移動することができます。その移動パターンは下図の通りです。 ナイトは移動のたびに、8つの可能な移動の中からランダムに1つを選択します。そして、ちょうどK回の移動を完了するか、チェス盤の外に出てしまうまで移動を続けます。この問題では、ナイトが移動を終えた時点で盤上に残っている確率を求めます。 例えば、入力が「3, 2, 0,