C++で選手ごとの的中確率からAが試合に勝つ確率を求める方法
2人のプレイヤーAとBが、試合の勝敗をかけたペナルティキックに挑む場面を考えてみましょう。4つの整数変数 a、b、c、d が与えられており、Aが先にペナルティを成功させる確率は a/b、Bが先に成功させる確率は c/d で表されます。
先にペナルティを決めた方が試合に勝利します。本記事では、この条件のもとで「Aが試合に勝つ確率」を求めるプログラムをC++で実装する方法を解説します。
入出力例
入力
a = 10, b = 20, c = 30, d = 40
出力
probability is 0.5333
入力
a = 1, b = 2, c = 10, d = 11
出力
probability is 0.523
解法のアプローチ
4つの整数変数 a、b、c、d の値を受け取ります。
Aの得点確率を e = a/b、Bの得点確率を f = c/d としてそれぞれ計算します。
Bが勝つ確率を全体の確率から差し引くことで、Aが勝つ確率を求めます。具体的には次の式を使用します。
e × (1 / (1 − (1 − f) × (1 − f)))
ここで、e はAが試合に勝つ確率、f はBが試合に勝つ確率を表します。この式は、勝負が繰り返される状況を無限等比級数の和として整理し、閉じた形(closed form)で表現したものです。
計算結果であるAの勝率を画面に出力します。
アルゴリズム
Start
Step 1→ 試合に勝つ確率を計算する関数を宣言する
double probab_win(int a, int b, int c, int d)
double e = (double)a / (double)b を宣言
double f = (double)c / (double)d を宣言
return (e * (1 / (1 - (1 - f) * (1 - f)))) を返す
Step 2→ main() 内で
int a = 10, b = 20, c = 30, d = 40 を宣言
probab_win(a, b, c, d) を呼び出す
Stop
C++での実装例
#include <bits/stdc++.h>
using namespace std;
// 試合に勝つ確率を計算する関数
double probab_win(int a, int b, int c, int d){
double e = (double)a / (double)b;
double f = (double)c / (double)d;
return (e * (1 / (1 - (1 - f) * (1 - f))));
}
int main(){
int a = 10, b = 20, c = 30, d = 40;
cout<<"probability is "<<probab_win(a, b, c, d);
return 0;
}
出力
上記のコードをコンパイルして実行すると、次の出力が得られます。
probability is 0.5333
まとめ
この問題のポイントは、整数同士の割り算を double 型にキャストして正確な確率値を得ること、そして繰り返し行われる勝負を幾何級数の公式で効率的に計算することです。a、b、c、d の値を入れ替えるだけで、さまざまな条件におけるAの勝率を簡単に求められるため、確率計算の練習題材としても最適です。
-
マルコフ連鎖における特定時刻の状態到達確率を求めるC++プログラム
本記事では、マルコフ連鎖(Markov Chain)において、初期状態から出発し、指定された時間が経過した時点で特定の状態へ到達する確率を求めるC++プログラムについて解説します。 マルコフ連鎖とは マルコフ連鎖とは、複数の「状態」と、ある状態から別の状態へ遷移する際の「遷移確率」から構成される確率過程(ランダムプロセス)です。状態間の遷移には単位時間が1単位かかるものとします。マルコフ連鎖の重要な特徴は、「次の状態」が現在の状態のみによって決まり、それ以前の履歴に依存しないというマルコフ性を持つ点です。 マルコフ連鎖は有向グラフとして表現できます。この問題を解くには、与えられたマルコフ連鎖
-
C++で数値の各桁の合計を計算するプログラム
ここでは、C++言語を使用して入力された整数の各桁の合計を計算する方法を紹介します。剰余演算子と整数除算を組み合わせたシンプルなアルゴリズムで実装できます。 プログラム例 #include<iostream> using namespace std; int main() { int x, s = 0; cout << Enter the number : ; cin >> x; while (x != 0) {