Jogging
Problem Description
Notice:Don’t output extra spaces at the end of one line.
Dodo bird is jogging on an infinite 2-d plane, starting from (x0,y0). For a point(x,y), it is regarded as good if and only if gcd(x,y)>1.
Dodo bird will walk infinite steps on the plane under the following strategy:
Assume he is currently at (x,y), let S be the set of good points among (x−1,y−1),(x−1,y),(x−1,y+1),(x,y−1),(x,y+1),(x+1,y−1),(x+1,y),(x+1,y+1), z be the size of S. He has a probability of 1z+1 to stay in (x,y), and he also has a probility of zz+1 to move to a point in S. If he chooses to move, the probility of going to any point in S is equal.
Define pt as the probability of coming back to (x0,y0) after walking t steps, please calculate limt→∞pt. It is guaranteed that the answer always exists.
Input
The first line contains an integer T(1≤T≤1000), indicating the number of test cases.
Each test case has one line, which contains two integers x,y(2≤x0,y0≤1012), indicating the position of the start point. It is guaranteed that gcd(x0,y0)>1.
Output
T lines, each line contains an irreducible fraction, indicating the answer.
Sample Input
3
18 16
18 6
18 8
Sample Output
0/1
1/1
2/7
思路
对于任意一张无向图,从 s 开始随机游走回到 s 的概率。经典结论就是,答案为 (s的度数+1)/(+1)/(整张图的总度数+n)+n)。我也不懂怎么证的,翻到了大佬的博客,里面有证明(顺便一提这个大佬打出了9题,太强了)链接
当s能游走到y=x这条线上时,它可以在这条线上无限的走,也就回不到原点了。概率就是0了。
接下来就是照着题解清的题了,直接bfs全图,记录度数就行了。
代码
#include<bits/stdc++.h>
#include<string>
using namespace std;
typedef long long ll;
const int mod=998244353;
const int inf=0x3f3f3f3f;
const int N=2e3+10;
ll gcd(ll a,ll b){
return b==0?a:gcd(b,a%b);
}
int a[8]={-1,-1,-1,0,0,1,1,1};
int b[8]={-1,0,1,-1,1,-1,0,1};
set<pair<ll,ll> >vis;
void bfs(ll x,ll y){
int ans1=0,ans2=0;
queue<pair<ll,ll> >q;
q.emplace(x,y);
vis.emplace(x,y);
while(q.size()){
tie(x,y)=q.front();
q.pop();
if(x==y){
ans1=0,ans2=1;
break;
}
ans2++;
for(int i=0;i<8;i++){
ll xx=x+a[i];
ll yy=y+b[i];
if(gcd(xx,yy)>1){
ans2++;
if(vis.count(make_pair(xx,yy)))
continue;
vis.insert(make_pair(xx,yy));
q.emplace(xx,yy);
}
}
if(!ans1)ans1=ans2;
}
int tp=gcd(ans1,ans2);
ans1/=tp,ans2/=tp;
printf("%d/%d\n",ans1,ans2);
}
int main()
{int t;
cin>>t;
while(t--){
ll x,y;
cin>>x>>y;
bfs(x,y);
}
}