#include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; typedef long long LL; typedef pair PII; #define MP make_pair #define PB push_back #define FF first #define SS second #define FORN(i, n) for (int i = 0; i < (int)(n); i++) #define FOR1(i, n) for (int i = 1; i <= (int)(n); i++) #define FORD(i, n) for (int i = (int)(n) - 1; i >= 0; i--) #define DEBUG(X) { cout << #X << " = " << (X) << endl; } #define PR0(A,n) { cout << #A << " = "; FORN(_,n) cout << A[_] << ' '; cout << endl; } #define MOD 1000000007 #define INF 2000000000 int GLL(LL& x) { return scanf("%lld", &x); } int GI(int& x) { return scanf("%d", &x); } const double EPS = 1e-10; typedef vector VI; typedef double T; typedef vector VT; typedef vector VVT; T GaussJordan(VVT &a, VVT &b) { const int n = a.size(); const int m = b[0].size(); VI irow(n), icol(n), ipiv(n); T det = 1; for (int i = 0; i < n; i++) { int pj = -1, pk = -1; for (int j = 0; j < n; j++) if (!ipiv[j]) for (int k = 0; k < n; k++) if (!ipiv[k]) if (pj == -1 || fabs(a[j][k]) > fabs(a[pj][pk])) { pj = j; pk = k; } if (fabs(a[pj][pk]) < EPS) { cerr << "Matrix is singular." << endl; exit(0); } ipiv[pk]++; swap(a[pj], a[pk]); swap(b[pj], b[pk]); if (pj != pk) det *= -1; irow[i] = pj; icol[i] = pk; T c = 1.0 / a[pk][pk]; det *= a[pk][pk]; a[pk][pk] = 1.0; for (int p = 0; p < n; p++) a[pk][p] *= c; for (int p = 0; p < m; p++) b[pk][p] *= c; for (int p = 0; p < n; p++) if (p != pk) { c = a[p][pk]; a[p][pk] = 0; for (int q = 0; q < n; q++) a[p][q] -= a[pk][q] * c; for (int q = 0; q < m; q++) b[p][q] -= b[pk][q] * c; } } for (int p = n-1; p >= 0; p--) if (irow[p] != icol[p]) { for (int k = 0; k < n; k++) swap(a[k][irow[p]], a[k][icol[p]]); } return det; } int n, m, k; vector board; string row; vector> A, B; inline int flatten(int i, int j) { return m * i + j; } const int MAXDIR = 4; int dx[MAXDIR] = {1, -1, 0, 0}; int dy[MAXDIR] = {0, 0, 1, -1}; map tunnels; int main() { GI(n); GI(m); GI(k); FORN(i, n) { cin >> row; board.PB(row); } FORN(i, k) { int i1, j1, i2, j2; GI(i1); i1--; GI(j1); j1--; GI(i2); i2--; GI(j2); j2--; tunnels[MP(i1, j1)] = MP(i2, j2); tunnels[MP(i2, j2)] = MP(i1, j1); } A.resize(n*m, vector(n*m, 0.0)); B.resize(n*m, vector(1, 0.0)); int si = -1; int sj = -1; FORN(i, n) { FORN(j, m) { if (board[i][j] == '#' || board[i][j] == '*') { A[flatten(i, j)][flatten(i, j)] = 1.0; B[flatten(i, j)][0] = 0.0; } else if (board[i][j] == '%') { A[flatten(i, j)][flatten(i, j)] = 1.0; B[flatten(i, j)][0] = 1.0; } else { if (board[i][j] == 'A') { si = i; sj = j; } vector valid; FORN(k, MAXDIR) { int ni = i + dx[k]; int nj = j + dy[k]; if (ni >= 0 && ni < n && nj >= 0 && nj < m && board[ni][nj] != '#') { if (tunnels.count(MP(ni, nj))) { auto t = tunnels[MP(ni, nj)]; valid.PB(flatten(t.FF, t.SS)); } else { valid.PB(flatten(ni, nj)); } } } // DEBUG(i); // DEBUG(j); // PR0(valid, valid.size()); if (valid.size() == 0) { A[flatten(i, j)][flatten(i, j)] = 1.0; B[flatten(i, j)][0] = 0.0; } else { A[flatten(i, j)][flatten(i, j)] = 1.0; for (auto& nxt : valid) { A[flatten(i, j)][nxt] = -1.0 / valid.size(); } } } } } /* FORN(i, n*m) { FORN(j, n*m) { cout << A[i][j] << " "; } cout << "\n"; } cout << "\n"; FORN(i, n*m) { cout << B[i][0] << "\n"; } */ double det = GaussJordan(A, B); cout << setprecision(12) << B[flatten(si, sj)][0] << endl; return 0; }