0
点赞
收藏
分享

微信扫一扫

Codeforces Round #763 (Div. 2) D.Robot Cleaner Revisit 期望/思维

穆风1818 2022-10-28 阅读 158


​​|——>传送门<——|​​

题目描述

给定一张的网格图,给定机器人起始位置和垃圾位置,每次机器人可以从运动,碰壁后对方向取反。每次可以将移动到的位置所在的横行和竖列清空掉,现在告诉你当机器人与垃圾同行同列时有概率清掉垃圾。问清理垃圾所需移动次数的期望。

题解

首先,机器人移动的过程一定存在循环节,也就是说从某点出发一直按照题目规则移动,一定会回到该点(证明略)。那么不妨设每步一循环,这步中有次与垃圾同行同列。

表示到第个点所移动的步数,那么可以列出期望的表达式:

对上式进行化简:

,设,等比数列求和后,由于,故数列收敛,取极限得

,发现为一等差数列项等比数列项的形式,运用错位相减法求和后同样取极限得

于是可得:

求和得:

那么直接模拟走的轮数求和即可。

#include <bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;

const int N = 2e5 + 10, MOD = 1e9 + 7;
int a[N], b[N];

inline int binpow(int x, int y, int mod, int res = 1){
for (; y; y >>= 1, (x *= x) %= mod) if (y & 1) (res *= x) %= mod;
return res;
}

inline int inv(int x){ return binpow(x, MOD - 2, MOD); }

inline void solve(){
int n, m, rb, cb, rd, cd, p; cin >> n >> m >> rb >> cb >> rd >> cd >> p;
p = p * inv(100) % MOD;
int pre = 1, idx = 0, ans = 0, dr = 1, dc = 1;
map<tuple<int, int, int, int>, bool> mp;
while(true){
if (rb + dr < 1 || rb + dr > n) dr *= -1;
if (cb + dc < 1 || cb + dc > m) dc *= -1;

if (mp[{rb, cb, dr, dc}]) break;
else mp[{rb, cb, dr, dc}] = true;
if (rb == rd || cb == cd) {
ans = (ans + idx * pre % MOD * p % MOD) % MOD;
pre = pre * (1 - p + MOD) % MOD;
}
rb += dr, cb += dc, idx++;
}
ans = ((ans + idx * pre % MOD) % MOD) * inv((1 - pre + MOD) % MOD) % MOD;
cout << ans << endl;
}

signed main(){
ios_base::sync_with_stdio(false), cin.tie(0);
int t = 0; cin >> t;
while(t--) solve();
return 0;
}


举报

相关推荐

0 条评论