题目来源:
http://acm.bnu.edu.cn/bnuoj/problem_show.php?pid=34986
题意:
一个人在玩桌面足球,有m行球员,每行球员有ai个,给出每个球员的宽度和相邻球员之间的距离,球从最左边射出,给出球的起点坐标跟方向向量,问能够到达最右边的概率。
思路:球员的相对位置固定,球员可以移动一定的距离。计算球经过球员的概率, 用1 - 球经过球员的概率 即为 可以穿过的概率。 枚举一遍所有行。
代码如下:
const int Max_N = 105 ; double w[Max_N] , tail[Max_N] , pos[Max_N] ; int main(){ int T ; scanf("%d" , &T) ; double W, l , X, Y , dx ,dy , dis , row , tot , y , ans ; int m , num , i , k = 1; while(T--){ ans = 1.0 ; scanf("%lf%lf" , &l , &W) ; scanf("%lf%lf%lf%lf" , &X, &Y , &dx , &dy) ; scanf("%d" , &m) ; while(m --){ tot = 0.0 ; pos[0] = 0.0 ; scanf("%lf%d" , &row , &num) ; y = Y + dy * (row - X) / dx ; for(i = 0 ; i < num ; i++){ scanf("%lf" , &w[i]) ; tot += w[i] ; } tail[0] = w[0] ; for(i = 1 ; i < num ; i++){ scanf("%lf", &dis) ; pos[i] = pos[i - 1] + w[i - 1] + dis ; tail[i] = pos[i] + w[i] ; tot += dis ; } double cnt = 0.0 , len = 0.0 ; double mov = W - tot ; for(i = 0 ; i < num ; i++){ // 枚举 cnt = 0.0 ; if(pos[i] <= y && (tail[i] + mov >= y) ){ if(tail[i] >= y) cnt = (pos[i] + mov <= y) ? mov : (y - pos[i]) ; else cnt = (pos[i] + mov >= y) ? w[i] : (tail[i] - y + mov) ; } len += cnt ; } if( mov == 0 ){ ans = 0 ; break ; } else ans = ans * (mov - len) / mov ; } printf("Case #%d: %.5lf " ,k++ , ans) ; } }