题意:求在坐标图上,随意游走无穷步,回到起点的概率。只能游走gcd(x,y) > 1的坐标。
题解:bfs+图上随机游走+概率
对于一张n个点的连通图,记起点为s,那么有一个结论,从s出发然后回到s的概率为 (s的度数+1)/(总度数+n)。
我们可以从s点开始bfs构建连通图,若图包含了对角线即x==y,那么图是无穷的,概率自然在极限下趋于0。
然后我们可以证明这张不包含对角线的连通图,它的大小只有几百,贴一下题解的证明:
bfs的时候直接记录度数即可。
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<queue>
#include<stack>
#include<cmath>
#include<vector>
#include<fstream>
#include<set>
#include<map>
#include<sstream>
#include<iomanip>
#define ll long long
using namespace std;
int t, d[8][2] = { {1, 0}, {-1, 0}, {0, 1}, {0, -1},{1, 1}, {1, -1}, {-1, 1}, {-1, -1} };
ll x, y, xx, yy;
ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
map<pair<int, int>, bool> m;
int main() {
//freopen("J.in", "r", stdin);
scanf("%d", &t);
while (t--) {
m.clear();
scanf("%lld%lld", &x, &y);
int flag = 0;
queue<pair<ll, ll> > q;
q.push(make_pair(x, y));
int num = 0;
m[make_pair(x, y)] = true;
++num;
pair<ll, ll> pp;
int ans = 0, ans1;
flag = 0;
while (!q.empty()) {
ll tx = q.front().first;
ll ty = q.front().second;
int id = m[make_pair(tx, ty)];
q.pop();
for (int i = 0; i < 8; i++) {
xx = tx + d[i][0], yy = ty + d[i][1];
pp = make_pair(xx, yy);
if (gcd(xx, yy) == 1) continue;
if (xx == yy) {
flag = 2;
break;
}
if (m[pp]) {
++ans;
//v[num].push_back(id);
continue;
}
m[pp] = true;
++num;
++ans;
//v[num].push_back(id);
q.push(pp);
}
if (flag == 2) break;
if (!flag) {
ans1 = ans;
flag = 1;
}
}
if (flag == 2) {
puts("0/1");
continue;
}
int fz = ans1 + 1;
int fm = ans + num;
int gc = gcd(fz, fm);
printf("%d/%d\n", fz / gc, fm / gc);
}
return 0;
}