ZJUT 地下迷宫 (高斯求期望)

http://cpp.zjut.edu.cn/ShowProblem.aspx?ShowID=1423

设dp[i]表示在i点时到达终点要走的期望步数,那么dp[i] = ∑1/m*dp[j] + 1,j是与i相连的点,m是与i相邻的点数,建立方程组求解。重要的一点是先判断DK到达不了的点,需要bfs预处理一下进行离散化,再建立方程组。

#include <stdio.h>
#include <iostream>
#include <map>
#include <set>
#include <list>
#include <stack>
#include <vector>
#include <math.h>
#include <string.h>
#include <queue>
#include <string>
#include <stdlib.h>
#include <algorithm>
#define LL __int64
//#define LL long long
#define eps 1e-9
#define PI acos(-1.0)
using namespace std;
const int INF = 0x3f3f3f3f;
const int mod = 10000007;

int dir[4][2] = {{-1,0},{1,0},{0,-1},{0,1}};
int n,m;
int cnt;
char g[15][15];
int equ,var;
double a[110][110];
double x[110];
int num[15][15];
int sx,sy,ex,ey;

struct node
{
    int x,y;
};

bool Gauss()
{
    int row,col,max_r;
    int i,j;
    row = col = 0;
    while(row < equ && col < var)
    {
        max_r = row;
        for(i = row+1; i < equ; i++)
            if(fabs(a[i][col]) > fabs(a[max_r][col]))
                max_r = i;
        if(max_r != row)
        {
            for(j = col; j <= var; j++)
                swap(a[row][j],a[max_r][j]);
        }
        if(fabs(a[row][col]) < eps)
        {
            col++;
            continue;
        }
        for(i = row+1; i < equ; i++)
        {
            if(fabs(a[i][col]) < eps) continue;
            double t = a[i][col] / a[row][col];
            a[i][col] = 0;
            for(j = col+1; j <= var; j++)
                a[i][j] -= a[row][j]*t;
        }
        row++;
        col++;
    }
    for(i = row; i < equ; i++)
    {
        if(fabs(a[i][var]) > eps)
            return false;
    }
    for(i = var-1; i >= 0; i--)
    {
        if(fabs(a[i][i]) < eps) continue;
        double t = a[i][var];
        for(j = i+1; j < var; j++)
            t -= a[i][j]*x[j];
        x[i] = t/a[i][i];
    }
    return true;
}

void bfs()
{
    cnt = 0;
    memset(num,-1,sizeof(num));
    queue <struct node> que;
    que.push((struct node){sx,sy});
    num[sx][sy] = cnt++;
    while(!que.empty())
    {
        struct node u = que.front();
        que.pop();
        for(int d = 0; d < 4; d++)
        {
            int x = u.x + dir[d][0];
            int y = u.y + dir[d][1];
            if(x >= 1 && x <= n && y >= 1 && y <= m && g[x][y] != 'X' && num[x][y] == -1)
            {
                que.push( (struct node){x,y} );
                num[x][y] = cnt++;
            }
        }
    }
}

int main()
{
	while(~scanf("%d %d",&n,&m))
	{
		for(int i = 1; i <= n; i++)
        {
            scanf("%s",g[i]+1);
            for(int j = 1; j <= m; j++)
            {
                if(g[i][j] == 'D')
                {
                    sx = i;
                    sy = j;
                }
                if(g[i][j] == 'E')
                {
                    ex = i;
                    ey = j;
                }
            }
        }
        bfs();
        equ = var = cnt;
		memset(a,0,sizeof(a));
		memset(x,0,sizeof(x));

		for(int i = 1; i <= n; i++)
		{
			for(int j = 1; j <= m; j++)
			{
				if(g[i][j] == 'X') continue;
				//printf("%d %d %d\n",i,j,M[make_pair(i,j)]);
				int t = num[i][j];
				if(t == -1) continue;
				if(g[i][j] == 'E')
				{
					a[t][t] = 1;
					a[t][cnt] = 0;
				}
				else
				{
					a[t][t] = 1;
					a[t][cnt] = 1;
					int c = 0;
					for(int d = 0; d < 4; d++)
					{
					    int ii = i + dir[d][0];
					    int jj = j + dir[d][1];
					    if(ii >= 1 && ii <= n && jj >= 1 && jj <= m && g[ii][jj] != 'X' && num[ii][jj] != -1)
                            c++;
					}
					for(int d = 0; d < 4; d++)
					{
                        int ii = i + dir[d][0];
					    int jj = j + dir[d][1];
					    if(ii >= 1 && ii <= n && jj >= 1 && jj <= m && g[ii][jj] != 'X' && num[ii][jj] != -1)
                        {
                            int tt = num[ii][jj];
                            a[t][tt] = -1.0/c;
                        }
					}
				}
			}
		}
		if(!Gauss())
            printf("tragedy!\n");
        else if(fabs(x[num[sx][sy]]-1000000)<eps)
            printf("tragedy!\n");
        else printf("%.2lf\n",x[num[sx][sy]]);
	}
	return 0;
}
时间: 2024-08-10 19:16:43

ZJUT 地下迷宫 (高斯求期望)的相关文章

hdu 4481 Time travel(高斯求期望)

http://acm.hdu.edu.cn/showproblem.php?pid=4418 读了一遍题后大体明白意思,但有些细节不太确定.就是当它处在i点处,它有1~m步可以走,但他走的方向不确定呢.后来想想这个方向是确定的,就是他走到i点的方向,它会继续朝着这个方向走,直到转向回头. 首先要解决的一个问题是处在i点处,它下一步该到哪个点.为了解决方向不确定的问题,将n个点转化为2*(n-1)个点.例如当n=4时由原来的0123变为012321,它对应的编号为012345,这样就不用管它哪个方

hdu 2262 高斯消元求期望

Where is the canteen Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 1070    Accepted Submission(s): 298 Problem Description After a long drastic struggle with himself, LL decide to go for some

hdu 3992 AC自动机上的高斯消元求期望

Crazy Typewriter Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 391    Accepted Submission(s): 109 Problem Description There was a crazy typewriter before. When the writer is not very sober, it

hdu 4418 高斯消元求期望

Time travel Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1480    Accepted Submission(s): 327 Problem Description Agent K is one of the greatest agents in a secret organization called Men in B

HDU4870_Rating_双号从零单排_高斯消元求期望

原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=4870 原题: Rating Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 654    Accepted Submission(s): 415 Special Judge Problem Description A little gir

HDU 3853 LOOPS(概率dp求期望啊)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3853 Problem Description Akemi Homura is a Mahou Shoujo (Puella Magi/Magical Girl). Homura wants to help her friend Madoka save the world. But because of the plot of the Boss Incubator, she is trapped in

hdu 4405 Aeroplane chess(概率DP 求期望__附求期望讲解方法)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4405 Problem Description Hzz loves aeroplane chess very much. The chess map contains N+1 grids labeled from 0 to N. Hzz starts at grid 0. For each step he throws a dice(a dice have six faces with equal p

滴滴出行2017秋招工程岗笔试题-地下迷宫

时间限制:1秒 空间限制:32768k 题目描述小青蛙有一天不小心落入了一个地下迷宫,小青蛙希望用自己仅剩的体力值P跳出这个地下迷宫.为了让问题简单,假设这是一个n*m的迷宫.迷宫每个位置为0或者1. 0代表这个位置有障碍物,小青蛙到达不了这个位置:1代表小青蛙可以达到的位置.小青蛙初始在(0,0)位置.地下迷宫的出口在(0,m-1)(保证这两个位置都是1,并且保证一定有起点到终点可达的路径).小青蛙在迷宫中水平移动一个单位距离需要消耗1点体力值.向上爬一个单位距离需要消耗3个体力值,向下移动不

HDU 4405 Aeroplane chess (概率DP求期望)

题意:有一个n个点的飞行棋,问从0点掷骰子(1~6)走到n点需要步数的期望 其中有m个跳跃a,b表示走到a点可以直接跳到b点. dp[ i ]表示从i点走到n点的期望,在正常情况下i点可以到走到i+1,i+2,i+3,i+4,i+5,i+6 点且每个点的概率都为1/6 所以dp[i]=(dp[i+1]+dp[i+2]+dp[i+3]+dp[i+4]+dp[i+5]+dp[i+6])/6  + 1(步数加一). 而对于有跳跃的点直接为dp[a]=dp[b]; #include<stdio.h>