Problem Description
You have been given a circle from 0 to n - 1. If you are currently at x, you will move to (x - 1) mod n or (x + 1) mod n with equal probability. Now we want to know the expected number of steps you need to reach x from 0.
Input
The first line contains one integer T — the number of test cases.
Each of the next T lines contains two integers n, x (0 ≤ x < n ≤ 1000) as we mention above.
Output
For each test case. Print a single float number — the expected number of steps you need to reach x from 0. The figure is accurate to 4 decimal places.
Example Input
3
3 2
5 4
10 5
Example Output
2.0000
4.0000
25.0000
题目大意
有一个从0~n-1的环,从一个点可以向左右两个点移动一步且概率相等,问从 0 移动到 x 的期望是多少
解题思路
E[p]表示从0节点到p节点走的步数的期望值,则E[x]=0;对于任意一个节点来说,可从左侧走过来,也可以是从右侧走过来,即有 E[p]=0.5(E[p-1]+1)+0.5(E[p+1]+1),化简则有 -0.5*E[p-1]+E[p]-0.5*E[p+1]=1。
则可得 n 个方程组,有 n 个未知量。高斯消元求解即可。
代码实现
#include <iostream>
#include <cstring>
#include <cmath>
#include<cstdio>
using namespace std;
#define maxn 1007
double a[maxn][maxn];
int equ,var;
double x[maxn];
bool free_x[maxn];
int n;
void gauss()
{
equ=n,var=n;
int i,j,k;
int max_r;
int col;
double temp;
col=0;
for(k=0;k<equ&&col<var;k++,col++)
{
max_r=k;
for(i=k+1;i<equ;i++)
{
if(fabs(a[i][col])-fabs(a[max_r][col])>0)
max_r=i;
}
if(max_r!=k)
{
for(j=k;j<var+1;j++)
swap(a[k][j],a[max_r][j]);
}
if(a[k][col]==0)
{
k--;
continue;
}
for(i=k+1;i<equ;i++)
{
if (a[i][col]!=0)
{
temp=a[i][col]/a[k][col];
for(j=col;j<var+1;j++)
{
a[i][j]=a[i][j]-a[k][j]*temp;
}
}
}
}
for (i=var-1;i>=0;i--)
{
temp=a[i][var];
for(j=i+1;j<var;j++)
{
if(a[i][j]!=0)
temp-=a[i][j]*x[j];
}
x[i]=temp/a[i][i];
}
return;
}
int main()
{
int T,xx;
scanf("%d",&T);
while(T--)
{
scanf("%d %d",&n,&xx);
memset(a,0,sizeof(a));
for(int i=0;i<n;i++)
{
if(i==xx)
{
a[i][i]=1;
a[i][n]=0;
continue;
}
a[i][i]=1;
a[i][n]=1;
a[i][(i-1+n)%n]=-0.5;
a[i][(i+1)%n]=-0.5;
}
gauss();
printf("%.4lf\n",x[0]);
}
return 0;
}