传送门:点击打开链接
题意:点球大战,轮流每队点射5个球,A先踢。如果当前比分已经能直接让比赛胜利接下来的球就不需要踢了。问最后的得分是题所给出的得分的概率
思路:暴力DFS,直接枚举哪些球进了哪些球没进,注意比赛提前结束这个特殊的剪枝就行。
#include<map>
#include<set>
#include<cmath>
#include<stack>
#include<queue>
#include<cstdio>
#include<string>
#include<vector>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<functional>
#define FIN freopen("input.txt","r",stdin)
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int MX = 100 + 5;
int Ga, Gb;
double P[MX][2], ans;
void DFS(double p, int a, int b, int A, int B, int turn) {
if(A > 5 || B > 5 || a > Ga || b > Gb) return;
bool sign = false;
if(5 - A + a < b) sign = true;
if(5 - B + b < a) sign = true;
if(a == Ga && b == Gb && (sign || (A == 5 && B == 5))) {
ans += p;
return;
}
if(sign) return;
if(!turn) {
DFS(p * P[A + 1][0], a + 1, b, A + 1, B, 1); //a射门成功
DFS(p * (1 - P[A + 1][0]), a, b, A + 1, B, 1); //a射门失败
} else {
DFS(p * P[B + 1][1], a, b + 1, A, B + 1, 0); //b射门成功
DFS(p * (1 - P[B + 1][1]), a, b, A, B + 1, 0); //b射门失败
}
}
int main() {
int ansk = 0; //FIN;
while(~scanf("%lf", &P[1][0])) {
ans = 0;
for(int i = 2; i <= 5; i++) {
scanf("%lf", &P[i][0]);
}
for(int i = 1; i <= 5; i++) {
scanf("%lf", &P[i][1]);
}
scanf("%d-%d", &Ga, &Gb);
DFS(1, 0, 0, 0, 0, 0);
printf("Case %d: %.2lf%%\n", ++ansk, ans * 100);
}
return 0;
}