Find text path through character matrix with recursive algorithm

时间:2015-10-30 21:56:57

标签: algorithm recursion

I'm trying to solve this question: http://www.spoj.com/problems/ALLIZWEL/

Find whether there is a path in the given matrix which makes the sentence “ALL IZZ WELL”.

There is a path from any cell to all its neighbouring cells.
A neighbour may share an edge or a corner.

Input Specification:
The first line consists of an integer t representing the number of test cases.
The first line of each test case consists of two integers R and C representing the number of rows and number of columns in the matrix.

Output Specification:
For each test case print “YES” if there is a path which makes the sentence “ALLIZZWELL”.
Else print “NO”.

For sample test cases, open the link.

My code:

#include <iostream>
#include <map>
#include <vector>
#include <string>
#include <utility>
#include <algorithm>
#include <stack>
#include <queue>
#include <climits>
#include <set>
using namespace std;

char matrix[101][101];
bool var;
int r,c;
bool check (string str,int pos, bool visited[101][101],int i, int j);
int main (void)
{
    int t,i,j;
    cin>>t;
    bool ans;
    while (t != 0)
    {
        int r,c,flag=0;
        cin>>r>>c;
        for ( i = 0; i < r; i++ )
        {
            for ( j = 0; j < c; j++ )
            {
                cin>>matrix[i][j];
            } 
        }
        string str = "ALLIZZWELL";
        int pos = 1;
        for ( i = 0; i < r; i++ )
        {
            for ( j = 0; j < c; j++ )
            {
                bool visited[101][101];
                for ( i = 0; i < 101; i++ )
                    for ( j = 0; j < 101; j++ )
                        visited[i][j] = false;
                visited[i][j] = true;
                if (matrix[i][j] == 'A') // for all possible starting positions
                ans = check(str,pos,visited,i,j); 
                if (ans == true)
                {
                    cout<<"YES\n";
                    flag = 1;
                    break;
                }
                if (flag == 1)
                    break;
            }
        }
        if (flag == 0)
            cout<<"NO\n";
        t--;
    }
    return 0;
}

bool check (string str,int pos, bool visited[101][101],int i, int j) // checking for all possible test cases
{
    bool result = false;
    if (pos == str.length() + 1)
        return true;
    if (i+1 < r && visited[i+1][j] != true && matrix[i+1][j] == str[pos])
    {
        visited[i+1][j] = true;
        result = result || check(str,pos+1,visited,i+1,j);
        if (result == false)
            visited[i+1][j] = false;
    }
    else if (i-1 >= 0 && visited[i-1][j] != true && matrix[i-1][j] == str[pos])
    {
        visited[i-1][j] = true;
        result = result || check(str,pos+1,visited,i-1,j);
        if (result == false)
            visited[i-1][j] = true;
    }
    else if (j+1 < c && visited[i][j+1] != true && matrix[i][j+1] == str[pos])
    {
        visited[i][j+1] = true;
        result = result || check(str,pos+1,visited,i,j+1);
        if (result == false)
            visited[i][j+1] = true;
    }
    else if (j-1 >= 0 && visited[i][j-1] != true && matrix[i][j-1] == str[pos])
    {
        visited[i][j-1] = true;
        result = result || check(str,pos+1,visited,i,j-1);
        if (result == false)
            visited[i][j-1] = true;
    }
    else if (i+1 < r && j+1 < c && visited[i+1][j+1] != true && matrix[i+1][j+1] == str[pos])
    {
        visited[i+1][j+1] = true;
        result = result || check(str,pos+1,visited,i+1,j+1);
        if (result == false)
            visited[i+1][j+1] = true;
    }
    else if (i+1 < r && j-1 >= 0 && visited[i+1][j-1] != true && matrix[i+1][j-1] == str[pos])
    {
        visited[i+1][j-1] = true;
        result = result || check(str,pos+1,visited,i+1,j-1);
        if (result == false)
            visited[i+1][j-1] = true;
    }
    else if (i-1 >= 0 && j+1 < c && visited[i-1][j+1] != true && matrix[i-1][j+1] == str[pos])
    {
        visited[i-1][j+1] = true;
        result = result || check(str,pos+1,visited,i-1,j+1);
        if (result == false)
            visited[i-1][j+1] = true;
    }
    else if (i-1 >= 0 && j-1 >= 0 && visited[i-1][j-1]!= true && matrix[i-1][j-1] == str[pos])
    {
        visited[i-1][j-1] = true;
        result = result || check(str,pos+1,visited,i-1,j-1);
        if (result == false)
            visited[i-1][j-1] = true;
    }
    return false;
}

The code is quite self-explanatory: I am trying all possible cases.

I am getting a WA in the third test case, i.e.

2 9
A.L.Z.E..
.L.I.W.L.

I tried debugging but I couldn't narrow down my problem.

1 个答案:

答案 0 :(得分:1)

The main problems are:

  1. Using i and j in the loop clearing visited (as well as the outer loops)
  2. Using r and c as global variables in check, but writing them as local variables in main
  3. Always returning false from check (instead of result)
  4. Only trying the first choice in check (turn "else if" into "if")
  5. Not clearing the value in ans
  6. Only breaking out of the inner loop, not both the i and j loop
  7. Terminating the search when pos gets to str.length()+1 instead of str.length()

It often helps to put some print statements in recursive functions like these, try them out on a simple example, and see whether the sequence of calls matches your expectations.