#include #include #include #include #include #include #include using namespace std; typedef vector VI; typedef vector VVI; typedef long long Long; typedef pair PII; #define INF 1000000000000000000LL #define FREE 0 #define BLOCK 1 #define BOMB 2 #define EXIT 4 struct Cell { int type; int id; double probToMove; int hasTunnel; vector adj; int other; }; int dx[] = {-1,0,0,1}; int dy[] = {0,1,-1,0}; struct Matrix { #define MOD 1000000007 double** MAT; int N,M; Matrix(int N,int M):N(N),M(M) { MAT = new double*[N]; for(int i = 0; i < N; ++i){ MAT[i] = new double[M]; for(int j = 0; j < M; ++j) MAT[i][j] = 0; } } Matrix(const Matrix &o):N(o.N),M(o.M){ MAT = new double*[N]; for(int i = 0; i < N; ++i){ MAT[i] = new double[M]; for(int j = 0; j < M; ++j) MAT[i][j] = o.MAT[i][j]; } } Matrix& operator=(const Matrix &o){ N = o.N; M = o.M; MAT = new double*[N]; for(int i = 0; i < N; ++i){ MAT[i] = new double[M]; for(int j = 0; j < M; ++j) MAT[i][j] = o.MAT[i][j]; } return *this; } ~Matrix(){ for(int i = 0; i < N;++i) delete[] MAT[i]; delete[] MAT; } static Matrix identity(int N) { Matrix A(N,N); for(int i = 0; i < N; ++i) A[i][i] = 1; return A; } Matrix operator+(const Matrix &M)const { Matrix A(this->rows() , M.cols()); for(int i = 0; i < this->rows(); ++i) { for(int j = 0; j < this->cols(); ++j) { A[i][j] = (MAT[i][j] + M.MAT[i][j]); } } return A; } Matrix operator*(const Matrix &M)const { Matrix A(this->rows() , M.cols()); if(this->cols() != M.rows())return A; int X = this->rows(); int Y = M.cols(); int Z = this->cols(); for(int i = 0; i < X; ++i) { for(int j = 0; j < Y; ++j) { A[i][j] = 0; for(int k = 0; k < Z; ++k) { A[i][j] += MAT[i][k] * M.MAT[k][j]; } } } return A; } Matrix operator*(int &n) { Matrix A(this->rows() , this->cols()); for(int i = 0; i < this->rows(); ++i) { for(int j = 0; j < this->cols(); ++j) { A[i][j] = (n * (*this)[i][j]); } } return A; } Matrix transponse()const{ Matrix r(cols(), rows()); for(int i = 0; i < rows(); ++i) for(int j = 0; j < cols(); ++j) r[j][i] = MAT[i][j]; return r; } Matrix pow(long long n) { Matrix A = identity((*this).rows()); long long hb = 1; while(hb < n)hb <<= 1; for(long long b = hb; b >= 1; b>>=1) { A = A * A; if (b & n) A = A * (*this); } return A; } double* operator[](int i){return MAT[i];} int rows()const{return N;} int cols()const{return M;} string toString() { string ans = "{\n"; for(int i = 0; i < this->rows(); ++i) { ans += "["; for(int j = 0; j < this->cols(); ++j) { char arr[30]; string app = (j==0?"":" "); sprintf(arr,"%lf",(*this)[i][j]); app += arr; ans += app; } ans += "]\n"; } ans += "}"; return ans; } #undef MOD }; int main(){ // freopen("input.txt", "r", stdin); int N,M,T; cin >> N >> M >> T; vector> V(N, vector(M)); int si , sj; for (int i = 0; i < N; ++i) { string s; cin >> s; for (int j = 0; j < M; ++j) { Cell &c = V[i][j]; c.hasTunnel = 0; if(s[j] == '0'){ c.type = FREE; }else if(s[j] == '#'){ c.type = BLOCK; }else if(s[j] == '*'){ c.type = BOMB; }else if(s[j] == 'A'){ c.type = FREE; si = i; sj = j; }else if(s[j] == '%'){ c.type = EXIT; } } } int SZ = 0; for (int i = 0; i < N; ++i) { for (int j = 0; j < M; ++j) { Cell &c = V[i][j]; if(c.type == FREE || c.type == EXIT){ c.id = SZ++; } } } for (int i = 0; i < T; ++i) { int i0,j0,i1,j1; cin >> i0 >> j0 >> i1 >> j1; i0--;j0--;i1--;j1--; Cell &a = V[i0][j0]; Cell &b = V[i1][j1]; a.hasTunnel = b.hasTunnel = 1; a.other = b.id; b.other = a.id; } // for (int i = 0; i < N; ++i) { // for (int j = 0; j < M; ++j) { // Cell &c = V[i][j]; // if(c.type == FREE)cout << c.id; // else cout << "#"; // cout << " "; // } // cout << endl; // } for (int i = 0; i < N; ++i) { for (int j = 0; j < M; ++j) { Cell &c = V[i][j]; if(c.type != FREE)continue; int cnt = 0; // cout << c.id << ": "; for (int k = 0; k < 4; ++k) { int ni = i + dx[k], nj = j + dy[k]; if(ni < 0 || nj < 0 || ni >= N || nj >= M)continue; Cell &nc = V[ni][nj]; if(nc.type != BLOCK) cnt++; if(nc.type == EXIT || nc.type == FREE){ if(nc.hasTunnel){ c.adj.push_back(nc.other); }else{ c.adj.push_back(nc.id); } // cout << c.adj.back() << " "; } } c.probToMove = cnt == 0 ? 0 : (1.0 / cnt); // cout << " --> " << c.probToMove << endl; } } Matrix MAT(SZ+1, SZ+1); Matrix O(SZ+1, 1); for (int i = 0; i < N; ++i) { for (int j = 0; j < M; ++j) { Cell &c = V[i][j]; if(c.type == FREE){ for(int a : c.adj){ MAT[c.id][a] = c.probToMove; } } if(c.type == EXIT){ O[c.id][0] = 1; } } } MAT[SZ][SZ] = 1; MAT[SZ][ V[si][sj].id ] = 1; int P = 100000; if(SZ < 100){ P = 100000; }else if(SZ < 300){ P = 100000; }else{ if(SZ < 350){ if(SZ < 330){ P = 10000; }else{ P = 100000; } } else{ P = 100000; } } printf("%0.10lf\n", (MAT.pow(P)*O)[SZ][0]); } // abcbcba