Circle
Time Limit: 2000ms Memory limit: 65536K 有疑问?点这里^_^
题目描述
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.
输入
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.
输出
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.
示例输入
3 3 2 5 4 10 5
示例输出
2.0000 4.0000 25.0000
提示
来源
2014年山东省第五届ACM大学生程序设计竞赛
示例程序
用高消水过去的,设dp[i]表示在位置i时到达x的期望步数
dp[i] = 0.5*(dp[(i + 1)%n] + 1) + 0.5 * (dp[(i - 1) % n] + 1) ;
注意(i - 1) % n 可能是负的,要加个n然后取模
把方程整理下
2 * dp[i] - dp[(i + 1) % n] - dp[(i - 1) % n] = 2;
然后对0-(n-1)每个点建立方程
/************************************************************************* > File Name: sdut2878.cpp > Author: ALex > Mail: [email protected] > Created Time: 2014年12月29日 星期一 22时00分21秒 ************************************************************************/ #include <map> #include <set> #include <queue> #include <stack> #include <vector> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int N = 1010; const double eps = 1e-12; double mat[N][N], x[N]; bool free_x[N]; int n, e; int Gauss() { int free_index, free_num; int max_r, k, col, var, equ; var = equ = n; memset (free_x, 1, sizeof(free_x)); memset (x, 0, sizeof(x)); for (k = col = 0; k < equ && col < var; ++k, ++col) { max_r = k; for (int i = k + 1; i < equ; ++i) { if (fabs(mat[i][col]) - fabs(mat[max_r][col]) > eps) { max_r = i; } } if (max_r != k) { for (int j = k; j < var + 1; ++j) { swap(mat[max_r][j], mat[k][j]); } } if (fabs(mat[k][col]) <= eps) { --k; continue; } for (int i = k + 1; i < equ; ++i) { if (fabs(mat[i][col]) <= eps) { continue; } double tmp = mat[i][col] / mat[k][col]; for (int j = col; j < var + 1; ++j) { mat[i][j] -= mat[k][j] * tmp; } } } for (int i = k; i < equ; ++i) { if (fabs(mat[i][var]) > eps) { return 0; } } if (k < var) { for (int i = k - 1; i >= 0; --i) { free_num = 0; for (int j = 0; j < var; ++j) { if (fabs(mat[i][j]) > eps && free_x[j]) { free_num++; free_index = j; } } if (free_num > 1) { continue; } double tmp = mat[i][var]; for (int j = 0; j < var; ++j) { if (j != free_index && fabs(mat[i][j]) > eps) { tmp -= mat[i][j] * x[j]; } } free_x[free_index] = 0; x[free_index] = tmp / mat[i][free_index]; } return var - k; } for (int i = var - 1; i >= 0; --i) { double tmp = mat[i][var]; for (int j = i + 1; j < var; ++j) { if (fabs(mat[i][j]) > eps) { tmp -= x[j] * mat[i][j]; } } x[i] = tmp / mat[i][i]; } return 1; } int main() { int t; scanf("%d", &t); while (t--) { scanf("%d%d", &n, &e); memset (mat, 0, sizeof(mat)); for (int i = 0; i < n; ++i) { if (i == e) { mat[i][i] = 1; mat[i][n] = 0; } else { mat[i][i] = 2; mat[i][(i + 1) % n] = -1; int t = (i - 1) % n; if (t < 0) { t = (t + n) % n; } mat[i][t] = -1; mat[i][n] = 2; } } Gauss(); printf("%.4f\n", x[0]); } return 0; }
时间: 2024-10-08 05:49:41