結果
| 問題 | No.173 カードゲーム(Medium) |
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2025-12-31 16:43:00 |
| 言語 | D (dmd 2.111.0) |
| 結果 |
AC
|
| 実行時間 | 1,277 ms / 3,000 ms |
| コード長 | 1,019 bytes |
| 記録 | |
| コンパイル時間 | 4,238 ms |
| コンパイル使用メモリ | 223,904 KB |
| 実行使用メモリ | 7,848 KB |
| 最終ジャッジ日時 | 2025-12-31 16:43:17 |
| 合計ジャッジ時間 | 15,778 ms |
|
ジャッジサーバーID (参考情報) |
judge3 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 10 |
ソースコード
module main;
// https://kmjp.hatenablog.jp/entry/2015/03/27/0900 より
// モンテカルロ法
import std;
int N;
int[] A, B;
int[] getRandArray(double p)
{
auto v = iota(0, N).array;
int[] r;
int x;
foreach (i; 0 .. N - 1) {
double d = uniform(0.0, 1.0);
if (d < p) x = 0;
else x = (1 + (N - 1 - i) * (d - p) / (1 - p)).to!int;
r ~= v[x];
v.remove(x);
}
r ~= v[0];
return r;
}
void main()
{
// 入力
double[2] P;
readln.chomp.formattedRead("%d %f %f", N, P[0], P[1]);
A = readln.split.to!(int[]);
B = readln.split.to!(int[]);
// 答えの計算
A.sort;
B.sort;
// AとBの点数の合計の半分
int T = (A.sum + B.sum) / 2;
// 試行回数とAの勝利回数
int total = 0, win = 0;
foreach (_; 0 .. 200_000) {
total++;
auto VA = getRandArray(P[0]);
auto VB = getRandArray(P[1]);
int x = 0;
foreach (y; 0 .. N)
if (A[VA[y]] > B[VB[y]])
x += A[VA[y]] + B[VB[y]];
win += x > T;
}
double ans = win;
ans /= total;
// 答えの出力
writefln("%.10f", ans);
}