Sicily 1946. Pipe

来源:互联网 发布:linux deploy中文版 编辑:程序博客网 时间:2024/06/08 20:01

1946. Pipe

Constraints

Time Limit: 5 secs, Memory Limit: 32 MB

Description

Fat Merlin is a fat mouse, he lives under the ground. There is an abandoned pipe system under the ground, it connects Merlin’s house with some other buildings. One day, Merlin found a warehouse through the pipe, the warehouse was filled with food, and he decided to come to this warehouse, enjoy the food every morning. Merlin also likes to tour in the pipes, he wants to know how many different simple paths are there from his house to the warehouse (A path is simple when the same position does not appear more than once during the path).
The pipe system can be considered as a matrix, consisting of M*N cells, where M is the number of rows and N is the number of columns. Each cell may contain one of the following types of pipes:
 


Note that type 11 and 12 are different. In type 12, the horizontal pipe and the vertical pipe are not connected with each other, but in type 11, they are connected; there is no pipe in type 0.
Merlin’s house and the warehouse are both outside the matrix. There is an entrance from which he can get into the pipe from his house, and an exit leading to the warehouse. After entering the entrance, he cannot go out of the pipe before he arrives at the exit.
The following two pictures show the last two test cases in sample input.


 



Given the position of the entrance and the exit on the boundary of the matrix, help Merlin to count how many simple paths are there from the entrance to the exit. 

Input

Input contains several test cases.
For each test case, the first line has two integers M and N (1 <= M, N <= 6);
Next M lines describe the matrix of pipe system, each line has N integers in range [0, 14], representing the type of pipes on each cell.
The position of entrance or exit is represented as a triple (R, C, D). R and C are integers and satisfy 1 <= R <= M, 1 <= C <= N. D is a character, it may be ‘U’, ‘D’, ‘L’ or ‘R’, representing the position is on the upper / lower / left / right side of cell (R,C).
The last line of each test case has two triples RS, CS, DS, RT, CT, DT, representing the position of the entrance and the exit. It is guaranteed that the entrance and the exit are at different positions, and they are both on the boundary of the matrix (if D is ‘U’, R must be 1; if D is ‘D’, R must be M; if D is ‘L’, C must be 1; if D is ‘R’, C must be N).
Input is terminated by EOF. 

Output

For each test case, output the answer on a single line. 

Sample Input

1 111 1 L 1 1 R2 211 1111 111 1 U 1 1 L3 36 4 05 13 26 3 01 1 U 2 3 R3 30 1 05 12 46 10 71 2 U 3 3 D

Sample Output

011

2

// Problem#: 1946// Submission#: 3589529// The source code is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License// URI: http://creativecommons.org/licenses/by-nc-sa/3.0/// All Copyright reserved by Informatic Lab of Sun Yat-sen University#include <stdio.h>#include <string.h>const int MAXN = 6;const int MAXP = MAXN * MAXN * 2 + 2;const int mSide[] = {0, 9, 6, 3, 10, 12, 5, 11, 14, 13, 7, 15};const char cDir[] = "ULRD";const int dx[] = {-1, 0, 0, 1};const int dy[] = {0, -1, 1, 0};int m;int n;int S, T;int a[MAXN][MAXN];int nNode;int pNode[MAXN][MAXN][4];int g[MAXP][MAXP];int deg[MAXP];int ans;bool flag[MAXP];int nAdj[MAXP];int adj[MAXP][MAXP];void buildNode() {    nNode = 2;    memset(pNode, -1, sizeof(pNode));    for (int i = 0; i < m; i++)        for (int j = 0; j < n; j++) {            scanf("%d", &a[i][j]);            int v = a[i][j];            int * p = pNode[i][j];            switch(v) {            case 12:                p[0] = p[3] = nNode++;                p[1] = p[2] = nNode++;                break;            case 13:                p[0] = p[1] = nNode++;                p[2] = p[3] = nNode++;                break;            case 14:                p[0] = p[2] = nNode++;                p[1] = p[3] = nNode++;                break;            default:                for (int k = 0; k < 4; k++) if ((mSide[v] >> k) & 1) p[k] = nNode;                nNode++;            }        }}void buildEdge() {    for (int i = 0; i < m; i++)        for (int j = 0; j < n; j++)            for (int k = 0; k < 4; k++) {                int u = pNode[i][j][k];                if (u < 0) continue;                int x = i + dx[k], y = j + dy[k];                if (x >= 0 && x < m && y >= 0 && y < n) {                    int v = pNode[x][y][3 - k];                    if (v >= 0) g[u][v] = g[v][u] = 1;                }            }}int getP() {    int x, y;    char d[2];    scanf("%d%d%s", &x, &y, d);    x--;    y--;    for (int i = 0; i < 4; i++) if (d[0] == cDir[i]) return pNode[x][y][i];    return -1;}void simplify() {    for (int i = 0; i < nNode; i++) {        deg[i] = 0;        for (int j = 0; j < nNode; j++) deg[i] += (g[i][j] > 0);    }    bool done;    do {        done = 1;        for (int i = 0; i < nNode; i++) if (deg[i] == 2) {            int u = -1, v = -1;            for (int j = 0; j < nNode; j++) if (g[i][j] > 0) {                if (u < 0) u = j;                else {v = j; break;}            }            if (g[u][v] > 0) deg[u]--, deg[v]--;            g[v][u] = g[u][v] = g[i][u] * g[i][v] + g[u][v];            deg[i] = -1;            g[i][u] = g[u][i] = 0;            g[i][v] = g[v][i] = 0;            done = 0;        }    } while (!done);}void go(int u, int cur) {    if (u == T) {        ans += cur;        return;    }    flag[u] = 1;    for (int i = 0; i < nAdj[u]; i++) {        int v = adj[u][i];        if (flag[v] || g[u][v] == 0) continue;        go(v, cur * g[u][v]);    }    flag[u] = 0;}int solve() {    buildNode();    S = getP();    T = getP();    if (S < 0 || T < 0) return 0;    memset(g, 0, sizeof(g));    g[0][S] = g[S][0] = 1;    g[1][T] = g[T][1] = 1;    buildEdge();    simplify();    if (g[0][1] > 0) return g[0][1];    for (int i = 2; i < nNode; i++) if (deg[i] >= 0) {        if (g[0][i] > 0) S = i;        if (g[1][i] > 0) T = i;    }    int c = g[0][S] * g[1][T];    g[S][0] = g[T][1] = 0;    memset(nAdj, 0 ,sizeof(nAdj));    for (int i = 2; i < nNode; i++) if (deg[i] >= 0) {        for (int j = 2; j < nNode; j++) if (deg[j] >= 0 && g[i][j] > 0) adj[i][nAdj[i]++] = j;    }    memset(flag, 0, sizeof(flag));    ans = 0;    go(S, 1);    return ans * c;}int main() {    while (scanf("%d%d", &m, &n) == 2) printf("%d\n", solve());    return 0;}                                 


0 0
原创粉丝点击