Google KickStart 2020 RoundB D题

Title: There is an arena with rows W and H. The robot is going from (1,1) to (W, H). There is a rectangular black hole in the arena with upper left coordinates (L, U) and lower right coordinates (R, D).

The robot can only go right or down, with probability 1/2. If the robot is in the last row, it can only go to the right; if the robot is in the last column, it can only go down.

Ask the robot the probability of successfully reaching (W, H) without falling into the black hole.

data range:

1 ≤ T ≤ 100.
1 ≤ U ≤ D ≤ H.
1 ≤ L ≤ R ≤ W.
1 ≤ W ≤ 10^5.
1 ≤ H ≤ 10^5.

Analysis: The robot will either pass from the lower left of the black hole or the upper right of the black hole, with time complexity O (n).

Note: Because "If the robot is in the last row, you can only go to the right; if the robot is in the last column, you can only go down", so the probability of the last row and the last column must be calculated separately!


void init_log2(){
    for(int i = 1; i < MAXN; ++i){
        Log2[i] = Log2[i - 1] + log2(i);
    }
}
void init_last(){
    last_r[1] = pow(2, Log2[1 + H - 2] - Log2[1 - 1] - Log2[H - 1] - (double)(1 + H - 2));
    for(int i = 2; i <= W; ++i){
        last_r[i] = last_r[i - 1] + 0.5 * pow(2, Log2[i + (H - 1) - 2] - Log2[i - 1] - Log2[(H - 1) - 1] - (double)(i + (H - 1) - 2));
    }
    last_c[1] = pow(2, Log2[W + 1 - 2] - Log2[W - 1] - Log2[1 - 1] - (double)(W + 1 - 2));
    for(int i = 2; i <= H; ++i){
        last_c[i] = last_c[i - 1] + 0.5 * pow(2, Log2[(W - 1) + i - 2] - Log2[(W - 1) - 1] - Log2[i - 1] - (double)((W - 1) + i - 2));
    }
}
bool judge(int x, int y){
    return x >= 1 && x <= W && y >= 1 && y <= H;
}
int main(){
    init_log2();
    int T;
    scanf("%d", &T);
    for(int Case = 1; Case <= T; ++Case){
        scanf("%d%d%d%d%d%d", &W, &H, &L, &U, &R, &D);
        init_last();
        int x = L - 1;
        int y = D + 1;
        double ans = 0;
        while(judge(x, y)){
            if(y == H){
                ans += last_r[x];
            }
            else{
                ans += pow(2, Log2[x + y - 2] - Log2[x - 1] - Log2[y - 1] - (double)(x + y - 2));
            }
            --x;
            ++y;
        }
        x = R + 1;
        y = U - 1;
        while(judge(x, y)){
            if(x == W){
                ans += last_c[y];
            }
            else{
                ans += pow(2, Log2[x + y - 2] - Log2[x - 1] - Log2[y - 1] - (double)(x + y - 2));
            }
            ++x;
            --y;
        }
        printf("Case #%d: %.8lf\n", Case, ans);
    }
    return 0;
}

  

Guess you like

Origin www.cnblogs.com/tyty-Somnuspoppy/p/12737033.html