hdu2262 高斯消元

题目:有一个地图,一个人从某个点出发,问走到花园的期望步数为多少

设某点的期望步数为Ei。

那么目标的Ei=0。

Ei=(Enext1+Enext2……Enextk)/k+1。

为什么是这个公式 因为 如果 Ei-1的期望应该等于所有从Ei出发的点的期望总和

bfs完 套一个高斯消元就ok了

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <string.h>
#include <cmath>
#include <queue>
using namespace std;
#define eps 1e-9
const int MAXN=450;
double a[MAXN][MAXN],x[MAXN];//方程的左边的矩阵和等式右边的值,求解之后x存的就是结果
int equ,var;//方程数和未知数个数
int Gauss(int cequ, int cvar)
{
    equ=cequ; var=cvar;
    int i,j,k,col,max_r;
    for(k=0,col=0;k<equ&&col<var;k++,col++)
    {
        max_r=k;
        for(i=k+1;i<equ;i++)
          if(fabs(a[i][col])>fabs(a[max_r][col]))
            max_r=i;
        if(fabs(a[max_r][col])<eps)continue;
        if(k!=max_r)
        {
            for(j=col;j<var;j++)
              swap(a[k][j],a[max_r][j]);
            swap(x[k],x[max_r]);
        }
        x[k]/=a[k][col];
        for(j=col+1;j<var;j++)a[k][j]/=a[k][col];
        a[k][col]=1;
        for(i=0;i<equ;i++)
          if(i!=k)
          {
              x[i]-=x[k]*a[i][col];
              for(j=col+1;j<var;j++)a[i][j]-=a[k][j]*a[i][col];
              a[i][col]=0;
          }
    }
    return 1;
}
char str[20][20];
bool falg[20][20];
int dx[]={0,0,1,-1};
int dy[]={1,-1,0,0};
void bfs(int n,int m)
{
    queue<int>Qy,Qx;
    memset(falg,false,sizeof(falg));
    while(!Qy.empty())Qy.pop();
    while(!Qx.empty())Qx.pop();
    for(int i=0; i<n; i++)
    for(int j=0; j<m; j++)
        if(str[i][j]=='$'){
            falg[i][j]=true;
            Qx.push(i);
            Qy.push(j);
        }


    while(!Qy.empty()){
        int ux=Qx.front();
        int uy=Qy.front();
        Qx.pop();
        Qy.pop();
        for(int i=0; i<4; i++)
        {
        int tx=ux+dx[i];
        int ty=uy+dy[i];
        if(tx>=0&&ty>=0&&tx<n&&ty<m&&str[tx][ty]!='#'&&falg[tx][ty]==false){
                falg[tx][ty]=true;
                Qy.push(ty);
                Qx.push(tx);
          }
        }
    }
}
int main()
{
    int n,m;
    while(scanf("%d%d",&n,&m)==2){
        for(int i=0; i<n; i++){
            scanf("%s",str[i]);
        }
        memset(a,0,sizeof(a));
        memset(x,0,sizeof(x));
        bfs(n,m);
        int sx=-1,sy=-1;
        for(int i=0; i<n; i++)
            for(int j=0; j<m; j++)
            {

                if(str[i][j]=='#')continue;
                 int cnt=0;
                if(str[i][j]=='$'){
                    a[i*m+j][i*m+j]=1;
                    x[i*m+j]=0;
                    continue;
                }
                if(str[i][j]=='@'){
                    sx=i; sy=j;
                }
                for(int k=0; k<4; k++){
                    int tx=i+dx[k];
                    int ty=j+dy[k];
                    if(tx>=0&&ty>=0&&tx<n&&ty<m&&str[tx][ty]!='#'&&falg[tx][ty]){
                        a[i*m+j][tx*m+ty]=-1;
                        cnt++;
                    }
                }
                a[i*m+j][i*m+j]=cnt;
                x[i*m+j]=cnt;
            }
        if(sx!=-1&&sy!=-1&&falg[sx][sy]&&Gauss(n*m,n*m)){
            printf("%.6lf\n",x[sx*m+sy]);
        }else{
          puts("-1");
        }
    }
    return 0;
}
View Code

 

posted @ 2015-09-14 15:51  来自大山深处的菜鸟  阅读(260)  评论(0编辑  收藏  举报