sdut2878----Circle

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

sdut2878----Circle的相关文章

【sdut2878】Circle

题目链接http://acm.sdut.edu.cn/onlinejudge2/index.php/Home/Index/problemdetail/pid/2878.html 题意 n个结点编号为0到n-1组成一个环.如果当前在结点x,那么它等概率的走向 (x+1)mod n,(x-1) 问从0到x的期望步数是多少 分析 高斯消元解决带环概率DP f[i]表示当前在i结点,走到x结点得期望步数.f[x]=0. f[i]=f[i+1]*0.5+f[i-1]*0.5+1 整理得到 1=f[i+1]

657. Judge Route Circle 判断线路成圆

Initially, there is a Robot at position (0, 0). Given a sequence of its moves, judge if this robot makes a circle, which means it moves back to the original place. The move sequence is represented by a string. And each move is represent by a characte

SVG圆形&lt;circle&gt; 标签

1 <?xml version="1.0" standalone="no"?> 2 <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" 3 "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> 4 5 <svg width="100%" height="100%" v

hzau 1208 Color Circle(dfs)

1208: Color Circle Time Limit: 1 Sec  Memory Limit: 1280 MBSubmit: 289  Solved: 85[Submit][Status][Web Board] Description There are colorful flowers in the parterre in front of the door of college and form many beautiful patterns. Now, you want to fi

java定义一个Circle类,包含一个double型的radius属性代表圆的半径,一个findArea()方法返回圆的面积

需求如下:(1)定义一个Circle类,包含一个double型的radius属性代表圆的半径,一个findArea()方法返回圆的面积. (2)定义一个类PassObject,在类中定义一个方法printAreas(),该方法的定义如下: public void printAreas(Cirlce c, int times) 在printAreas方法中打印输出1到time之间的每个整数半径值,以及对应的面积.例如,times为5,则输出半径1,2,3,4,5,以及对应的圆面积. 在main方法

HDU 5343 MZL&#39;s Circle Zhou

MZL's Circle Zhou Time Limit: 1000ms Memory Limit: 131072KB This problem will be judged on HDU. Original ID: 534364-bit integer IO format: %I64d      Java class name: Main MZL's Circle Zhou is good at solving some counting problems. One day, he comes

ZOJ 3321 Circle(并查集啊)

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=3731 Your task is so easy. I will give you an undirected graph, and you just need to tell me whether the graph is just a circle. A cycle is three or more nodes V1, V2, V3, ...Vk, such th

HDU-5868 Different Circle Permutation

Problem DescriptionYou may not know this but it's a fact that Xinghai Square is Asia's largest city square. It is located in Dalian and, of course, a landmark of the city. It's an ideal place for outing any time of the year. And now: There are N chil

1.(1)编写一个接口ShapePara,要求: 接口中的方法: double getArea():获得图形的面积。double getCircumference():获得图形的周长 (2)编写一个圆类Circle,要求:圆类Circle实现接口ShapePara。 该类包含有成员变量: radius:public 修饰的double类型radius,表示圆的半径。 x:private修饰的dou

package jiekou1; public interface ShapePara { //定义常量PI final double PI=3.14; //定义抽象方法 //获得图形面积 double getArea(); //获得图形周长 double getCircumference(); } package jiekou1; public class Circle implements ShapePara { //定义成员变量 public double radius; public d

hdu 5343 MZL&#39;s Circle Zhou SAM

MZL's Circle Zhou 题意:给定两个长度不超过a,b(1 <= |a|,|b| <= 90000),x为a的连续子串,b为y的连续子串(x和y均可以是空串):问x+y形成的不同串的个数? 误区:开始一门心思想着求出总的可形成的字符串个数,再减去a,b中相同的子串重叠的部分:想通过连续插入a+b得到的SAM并不能获得信息:因为x,y是任意的子串,连续插入导致一定是a的后缀和b的前缀 正解:直接在计算有不同子串时,就不去计算重复的 <=>对于一个可能出现x后缀和y前缀相同