现在的位置: 首页 > 综合 > 正文

sdut2878—-Circle

2019年02月17日 ⁄ 综合 ⁄ 共 2538字 ⁄ 字号 评论关闭

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: 405045132@qq.com 
    > 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;
}

抱歉!评论已关闭.