hdu2262 高斯消元
题目:有一个地图,一个人从某个点出发,问走到花园的期望步数为多少
设某点的期望步数为Ei。
那么目标的Ei=0。
Ei=(Enext1+Enext2……Enextk)/k+1。
为什么是这个公式 因为 如果 Ei-1的期望应该等于所有从Ei出发的点的期望总和
bfs完 套一个高斯消元就ok了
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#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; }