ZOJ2929 Penalty Kick(概率)
题目挺水的,但由于其独特的阅读量比赛的时候没发现这道水题,在此做一下翻译,如果有人搜到这翻译的话有帮助的话自然最好啦。
中国队平局进入最后的点球决胜局,首先抛硬币决定谁先罚球,然后先是罚五球,如果罚的过程发现某一方不可能再胜出了,那么就不需要再踢下去。假如踢完5球之后还是平局,那么就由剩下的人继续踢球,已经踢过的人可以再踢的条件是他的所有队友都踢过了,所以先是前5个人踢,然后后6个人踢,如果其中一方比对方多一分就直接结束了,否则的话继续踢下去,如果11个都踢完了就再重复的踢一下,不停地重复直至决出胜负。
犯了个SB错误,while(~scanf("%d",&tmp)!=EOF) 然后我就不停地TLE了。
#pragma warning(disable:4996) #include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<string> #include<vector> using namespace std; double my[15]; double en; double tp; double kp; double hp; void dfs(int step, int u, int v, double p) { if (step == 6){ if (u > v) tp += p; if (v > u) kp += p; return; } double p1 = p*my[step]; double p2 = p*(1 - my[step]); if (u > v + 5 - step) tp += p1*en + p2*(1 - en); else if (v > u + 5 - step) kp += p1*en + p2*(1 - en); else dfs(step + 1, u, v, p1*en + p2*(1 - en)); if (u + 1 > v + 5 - step) tp += p1*(1 - en); else if (v > u + 1 + 5 - step) kp += p1*(1 - en); else dfs(step + 1, u + 1, v, p1*(1 - en)); if (u > v + 1 + 5 - step) tp += p2*en; else if (v + 1 > u + 5 - step) kp += p2*en; else dfs(step + 1, u, v + 1, p2*en); } int main() { int tmp; while (~scanf("%d", &tmp)) { my[1] = double(tmp) / 100; for (int i = 2; i <= 11; i++){ scanf("%d", &tmp); my[i] = double(tmp) / 100; } scanf("%d", &tmp); en = double(tmp) / 100; sort(my + 1, my + 1 + 11); reverse(my + 1, my + 1 + 11); tp = kp = 0; dfs(1, 0, 0, 1); hp = 1 - tp - kp; for (int i = 6; i <= 11; i++){ tp += hp*(my[i] * (1 - en)); hp = hp*(my[i] * en + (1 - my[i])*(1 - en)); } for (int k = 1; k <= 100; k++){ for (int i = 1; i <= 11; i++){ tp += hp*(my[i] * (1 - en)); hp = hp*(my[i] * en + (1 - my[i])*(1 - en)); } } tp *= 100; printf("%.4lf\n", tp); } return 0; }