Football on Table
题意:一些杆上有人,人有一个宽度,然后现在有一个球射过去,要求出球不会碰到任何人的概率
思路:计算出每根杆的概率,之后累乘,计算杆的概率的时候,可以先把每块人的区间长度再移动过程中会覆盖多少长度累加出来,然后(1 总和/可移动距离)就是不会碰到的概率
#include
#include
#include
const double eps = 1e-8; int t, n; double l, w, x, y, dx, dy; struct gan { double len; int num; double r[105]; double d[105]; double sumd; void init() { sumd = 0; memset(r, 0, sizeof(r)); memset(d, 0, sizeof(d)); } } g; double cal(gan g) { double yy = g.len * dy / dx + y; double yi = w - g.sumd; double down = 0, up = g.r[0]; double ans = 0; for (int i = 0; i < g.num; i++) { if (up + yi > yy && down < yy) { if (up > yy) { if (down + yi > yy) ans += yy - down; else ans += yi; } else { if (down + yi > yy) ans += g.r[i]; else ans += yi - (yy - up); } } down = up + g.d[i]; up = down + g.r[i + 1]; } return 1.0 - ans / yi; } int main() { int cas = 0; scanf("%d", &t); while (t--) { double ans = 1; scanf("%lf%lf", &l, &w); scanf("%lf%lf%lf%lf", &x, &y, &dx, &dy); scanf("%d", &n); for (int i = 0; i < n; i++) { g.init(); scanf("%lf%d", &g.len, &g.num); for (int j = 0; j < g.num; j++) { scanf("%lf", &g.r[j]); g.sumd += g.r[j]; } for (int j = 0; j < g.num - 1; j++) { scanf("%lf", &g.d[j]); g.sumd += g.d[j]; } g.d[g.num - 1] = 0; ans *= cal(g); } printf("Case #%d: %.5lf\n", ++cas, ans); } return 0; }