[丘班 2026 除夕夜跨年赛] 踢足球 / soccer 题解
[丘班 2026 除夕夜跨年赛] 踢足球 / soccer 题解
hydroxy
·
2026-02-10 20:22:11
·
个人记录
第一步:抽签
枚举队伍 $4$ 的可能对手:
- 对手是 $1$:那么半决赛是 ($4$ vs $1$) 和 ($2$ vs $3$)
- 对手是 $2$:那么半决赛是 ($4$ vs $2$) 和 ($1$ vs $3$)
- 对手是 $3$:那么半决赛是 ($4$ vs $3$) 和 ($1$ vs $2$)
这三种情况的概率相等,因为固定队伍 $4$,从剩下 $3$ 队里随机抽一个对手,每个概率 $\frac{1}{3}$。
---
**第二步:计算概率**
设 $P_{win}(a,b)$ 表示 $a$ 队战胜 $b$ 队的概率,规则题中已给:
- 如果 $v_a > v_b$,则 $a$ 是强者,概率 $= \frac{v_a \times (1-p_b)}{v_a + v_b}$;
- 如果 $v_a < v_b$,则 $b$ 是强者,$a$ 赢的概率 $= 1 - \frac{v_b \times (1-p_a)}{v_b + v_a}$;
- 如果 $v_a = v_b$,概率 $= 0.5$。
步骤:
1. 枚举队伍 $4$ 在半决赛的对手 $o \in \{1,2,3\}$;
2. 计算 $4$ 战胜 $o$ 的概率 $P_{sf} = P_{win}(4, o)$;
3. 另一半区是剩下的两个队 $x$ 和 $y$,计算 $x$ 战胜 $y$ 的概率 $P_{xy}$,然后决赛对手可能是 $x$ 或 $y$,要分别考虑:
- 如果 $x$ 胜 $y$,概率 $P_{xy}$,那么决赛是 $4$ 对 $x$,$4$ 赢决赛概率 $P_{win}(4, x)$,这一分支的总贡献 $= P_{sf} \times P_{xy} \times P_{win}(4, x)$;
- 如果 $y$ 胜 $x$,概率 $1 - P_{xy}$,那么决赛是 $4$ 对 $y$,$4$ 赢决赛概率 $P_{win}(4, y)$,贡献 = $P_{sf} \times (1-P_{xy}) \times P_{win}(4, y)$;
4. 把这个分支的总夺冠概率加起来,再乘以 $ \frac{1}{3} $(该抽签概率)。
---
**代码**
```cpp
#include
using namespace std;
int v[4];
double p[4];
double win(int a, int b){
if(v[a] == v[b]){
return 0.5;
}
if(v[a] > v[b]){
return (v[a]*(1.0-p[b]))/(v[a]+v[b]);
}
else{
return 1.0 - (v[b]*(1.0-p[a]))/(v[b]+v[a]);
}
}
int main(){
for(int i=0;i<4;i++){
cin>>v[i]>>p[i];
}
double tot = 0.0;
for(int opp : {0, 1, 2}){
double p = win(3,opp);
vector
for (int i : {0, 1, 2}){
if (i != opp) {
t.push_back(i);
}
}
int x = t[0], y = t[1];
double px = win(x, y);
double py = 1.0 - px;
double pfin = px*win(3,x) + py*win(3,y);
tot += (p*pfin)/3.0;
}
cout< return 0; } ``` SPJ: ```cpp #include "testlib.h" #include int main(int argc, char* argv[]) { registerTestlibCmd(argc, argv); const double EPS = 1e-6; double pans = ouf.readDouble(); double jans = ans.readDouble(); ensuref(std::isfinite(pans), "Participant output is not a finite number"); if (fabs(pans - jans) <= EPS) { quitf(_ok, "Answer accepted."); } else { quitf(_wa, "Wrong answer: expected %.6f, found %.6f", jans, pans); } } ```