本文主要是介绍山东省第五届ACM省赛 Circle(高斯消元),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
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;
}
这篇关于山东省第五届ACM省赛 Circle(高斯消元)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!