sdut 2878 圆圈

[ 题目描述]
现在有一个圆圈, 顺时针标号分别从 0 到 n-1, 每次等概率顺时针走一步或者逆时针走一步,
即如果你在 i 号点,你有 1/2 概率走到((i-1)mod n)号点,1/2 概率走到((i+1)mod n)号点。问
从 0 号点走到 x 号点的期望步数。
[ 输入]
第一行包含一个整数 T,表示数据的组数。
接下来有 T 行,每行包含两个整数 n, x。
T<=10, 0<=x<n<=300;
[ 输出]
对于每组数据,输出一行,包含一个四位小数表示答案。
[ 样例输入]
3
3 2
5 4
10 5
[ 样例输出]
2.0000
4.0000
25.0000
[ 数据范围]
对于 30% 的数据,n<=20
对于 50% 的数据,n<=100
对于 70% 的数据,n<=200
对于 100%的数据,n<=300

期望公式:
E[x]=0 (x==0);
E[x]=0.5*(E[x-1]+1)+0.5*(E[x+1]+1); (x!=0)
移项得,-E[i-1]*0.5+E[i]-E[i+1]*0.5=1
n 个方程高斯消元求解。

但有一个奇技淫巧

我们发现答案只有整数,于是打表,发现ans=(n-x)*x

%%%%%YZD佬orz

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 using namespace std;
 5 int main()
 6 {
 7   freopen("circle.in","r",stdin);
 8   freopen("circle.out","w",stdout);
 9   int T;
10   cin>>T;
11   while(T--)
12   {
13     int a,b;
14     cin>>a>>b;
15     cout<<b*(a-b)<<".0000"<<endl;
16   }
17   return 0;
18 }

 但这毕竟是奇技淫巧,还是上正解

 

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 using namespace std;
 7 double a[302][302];
 8 int n;
 9 int main()
10 {
11     int i,j,now,k,x,T;
12     freopen("circle.in","r",stdin);
13     freopen("circle.out","w",stdout);
14     cin>>T;
15     while (T--)
16     {
17     cin>>n>>x;
18     memset(a,0,sizeof(a));
19     for (i=0; i<=n-1; i++)
20     {
21         if (i==x)
22         {
23             a[i+1][i+1]=1;
24             a[i+1][n+1]=0;
25         }
26         else
27         {
28             a[i+1][i+1]=1;
29             a[i+1][(i-1+n)%n+1]=a[i+1][(i+1)%n+1]=-0.5;
30             a[i+1][n+1]=1;
31         }
32     }
33     for (i=1; i<=n; i++)
34     {
35         now=i;
36         for (j=i+1; j<=n; j++)
37             if (fabs(a[now][i])<fabs(a[j][i]))
38                 now=j;
39         for (j=i; j<=n+1; j++)
40             swap(a[now][j],a[i][j]);
41         for (j=i+1; j<=n+1; j++)
42             a[i][j]/=a[i][i];
43         a[i][i]=1;
44         for (j=i+1; j<=n; j++)
45         {
46             for (k=i+1; k<=n+1; k++)
47                 a[j][k]-=a[i][k]*a[j][i];
48             a[j][i]=0;
49         }
50     }
51     for (i=n; i>=1; i--)
52     {
53         for (j=i+1; j<=n; j++)
54         {
55             a[i][n+1]-=a[i][j]*a[j][n+1];
56             a[i][j]=0;
57         }
58         a[i][n+1]/=a[i][i];
59         a[i][i]=1;
60     }
61     printf("%.4lf\n",a[1][n+1]);
62     }
63 }

 

posted @ 2017-10-10 14:23  Z-Y-Y-S  阅读(249)  评论(0编辑  收藏  举报