Last year I participated in six Kick Start rounds in total and successfully got Google’s internship offer this year. Unfortunately, because of the pandemic, all Google China summer internship programs were canceled. This year, for full-time recruiting, I still need to continue participating in Kick Start. Although today’s Round B was at 7 a.m., many classmates still joined. Unfortunately, my time complexity for the last problem was too high, and the large test set TLE’d.
Bike Tour
A warm-up problem. Traverse mountains once and find positions higher than both neighbors.
During the contest, I only solved the small case. The large data set TLE’d.
The idea is simple: use DP to calculate the probability of reaching each grid cell.
dp[i][j] = 0.5 * dp[i-1][j] + 0.5 * dp[i][j-1].
Then calculate the sum of probabilities of reaching the top and left sides of the hole. Multiplying by 0.5 gives the probability of falling into the hole. To avoid handling the special cases at the bottom and right boundaries, when the hole touches the bottom, we can expand the hole to the left and intercept the probability that must fall into the hole earlier. The case where the hole touches the right boundary is handled similarly.
Time complexity: O(W * T), Space complexity: O(W).
intmain(){ int T; cin >> T; // preprocess log(x!) logfactor[0] = 0; for (int i = 1; i < 2 * MAX_WIDTH; ++i) { logfactor[i] = logfactor[i-1] + log2l(i); }
auto dp = [&](int i, int j) -> double { returnCombinationDivide2N(i + j, j); }; for (int iCase = 1; iCase <= T; ++iCase) { int W, H, L, U, R, D; cin >> W >> H >> L >> U >> R >> D; --L; --U; double ans = 0; if (W > MAX_WIDTH || H > MAX_WIDTH) { ans = 1; } elseif (D == H && R == W) { ans = 1; } else { if (D == H) { // 触底 L = 0; } if (R == W) { // 触右 U = 0; } if (U == 0 && L == 0) { ans = 1; } else { if (U > 0) { for (int i = L; i < R; ++i) { ans += 0.5 * dp(i, U - 1); } } if (L > 0) { for (int i = U; i < D; ++i) { ans += 0.5 * dp(L - 1, i); } } } } cout << "Case #" << iCase << ": " << (1 - ans) << endl; }