4

I have a matrix with 0s and 1s. I can start from any cell. I want to know what is the minimum number of steps(up,down,left,right) required to cover all possible 1s. I can start from 0 or 1.

Example:

0 1 0 
1 1 1
0 1 0

Start from (2,2) within 1 step I can reach all the 1s. I relate this to an adjacency matrix of a unweighted undirected graph. Essentially I need to find the farthest neighbour when I can start from ANY point. I could simply have used BFS/DFS and kept a counter if I could start from only the vertices, however this poses a problem.

Dominique Fortin
  • 2,212
  • 15
  • 20
someone1
  • 115
  • 1
  • 11
  • What problem, specifically, are you running into? – templatetypedef Jan 01 '16 at 17:53
  • I'm guessing this must be some standard algorithm, but can't understand which one to use, or what to do for this problem. Should I go to each cell and use BFS using the counter? but if I am going to a cell which has 0 (not a vertex on the graph) how do I do use DFS? Any hint/help in solving this problem: Given the matrix, finding the steps starting from any point to find the number of steps to cover all 1s. – someone1 Jan 01 '16 at 17:59
  • Your question doesn't state how the number of steps shohuld be minimized. Is it the number of steps needed to get to the furthest `1` from the start? The sum of all steps? The length of a all `1` visiting path? – Zeta Jan 02 '16 at 11:45
  • @someone1 I have added an 8-way solution too – Khaled.K Jan 02 '16 at 21:02

2 Answers2

0

While you can think of a 0/1 matrix as an adjacency matrix for some graph, in this particular case the graph that you really care about is the one where every node is a cell in the matrix and each node is adjacent to the cells directly adjacent to it in the matrix.

One option for solving this problem would be to run multiple breadth-first searches, one starting at each node in the graph, and to record the maximum distance from each node to any 1 in the graph. You can then choose the node that minimizes this maximum distance.

templatetypedef
  • 362,284
  • 104
  • 897
  • 1,065
  • I'm relatively new to this, any chance we could discuss this on chat? Would become slightly simpler, only if you're okay with that. I have a couple of doubts! – someone1 Jan 01 '16 at 18:37
0

My approach would be to spread from the starting cell upward & downward, then on each row spread through that row toward both ends, by keeping the number steps taken so far.

All routes from the starting point to a cell, by moving either vertically or horizontally, would result in the same Manhattan Distance.

Solution, Try Here.

#include<stdio.h>

// test

int main (void)
{
    int g[5][5] =
    {
      { 1,0,0,0,0 },
      { 0,0,1,0,0 },
      { 0,1,1,1,1 },
      { 1,0,1,0,0 },
      { 0,0,0,1,0 }
    };

    printf("\n 4-way solution = %d \n", mmd4(5,5,g, 2,2));
    printf("\n 8-way solution = %d \n", mmd8(5,5,g, 2,2));

    return 0;
}

8-way Solution

int mmd8(int h, int w, int g[h][w], int x, int y)
{
    putchar('#');
    return max8(mmd8_up   (h,w,g,x-1,y  ,1),
                mmd8_down (h,w,g,x+1,y  ,1),
                mmd8_left (h,w,g,x  ,y-1,1),
                mmd8_right(h,w,g,x  ,y+1,1),

                mmd8_uleft (h,w,g,x-1,y-1,1),
                mmd8_uright(h,w,g,x-1,y+1,1),
                mmd8_dleft (h,w,g,x+1,y-1,1),
                mmd8_dright(h,w,g,x+1,y+1,1));
}

int mmd8_up(int h, int w, int g[h][w], int x, int y, int steps)
{
    if (base_case(h,w,x,y)) return 0;
    putchar('U');
    return max4(g[x][y]?steps:0,
           mmd8_up    (h,w,g,x-1,y  ,steps+1),
           mmd8_uleft (h,w,g,x-1,y-1,steps+1),
           mmd8_uright(h,w,g,x-1,y+1,steps+1));
}

int mmd8_down(int h, int w, int g[h][w], int x, int y, int steps)
{
    if (base_case(h,w,x,y)) return 0;
    putchar('D');
    return max4(g[x][y]?steps:0,
           mmd8_down  (h,w,g,x+1,y  ,steps+1),
           mmd8_dleft (h,w,g,x+1,y-1,steps+1),
           mmd8_dright(h,w,g,x+1,y+1,steps+1));
}

int mmd8_left(int h, int w, int g[h][w], int x, int y, int steps)
{
    if (base_case(h,w,x,y)) return 0;
    putchar('L');
    return max2(g[x][y]?steps:0,
           mmd8_left (h,w,g,x  ,y-1,steps+1),
           mmd8_uleft(h,w,g,x-1,y-1,steps+1),
           mmd8_dleft(h,w,g,x+1,y-1,steps+1));
}

int mmd8_right(int h, int w, int g[h][w], int x, int y, int steps)
{
    if (base_case(h,w,x,y)) return 0;
    putchar('R');
    return max2(g[x][y]?steps:0,
           mmd8_right (h,w,g,x  ,y+1,steps+1),
           mmd8_uright(h,w,g,x-1,y+1,steps+1),
           mmd8_dright(h,w,g,x+1,y+1,steps+1));
}

int mmd8_uleft(int h, int w, int g[h][w], int x, int y, int steps)
{
    if (base_case(h,w,x,y)) return 0;
    putchar('W');
    return max2(g[x][y]?steps:0,
           mmd8_uleft(h,w,g,x-1,y-1,steps+1));
}

int mmd8_uright(int h, int w, int g[h][w], int x, int y, int steps)
{
    if (base_case(h,w,x,y)) return 0;
    putchar('X');
    return max2(g[x][y]?steps:0,
           mmd8_uright(h,w,g,x-1,y+1,steps+1));
}

int mmd8_dleft(int h, int w, int g[h][w], int x, int y, int steps)
{
    if (base_case(h,w,x,y)) return 0;
    putchar('Y');
    return max2(g[x][y]?steps:0,
           mmd8_dleft(h,w,g,x+1,y-1,steps+1));
}

int mmd8_dright(int h, int w, int g[h][w], int x, int y, int steps)
{
    if (base_case(h,w,x,y)) return 0;
    putchar('Z');
    return max2(g[x][y]?steps:0,
           mmd8_dright(h,w,g,x+1,y+1,steps+1));
}

4-way Solution

int mmd4(int h, int w, int g[h][w], int x, int y)
{
    putchar('#');
    return max4(mmd_up   (h,w,g,x-1,y  ,1),
                mmd_down (h,w,g,x+1,y  ,1),
                mmd_left (h,w,g,x  ,y-1,1),
                mmd_right(h,w,g,x  ,y+1,1));
}

int mmd_up(int h, int w, int g[h][w], int x, int y, int steps)
{
    if (base_case(h,w,x,y)) return 0;
    putchar('U');
    return max4(g[x][y]?steps:0,
           mmd_up   (h,w,g,x-1,y  ,steps+1),
           mmd_left (h,w,g,x  ,y-1,steps+1),
           mmd_right(h,w,g,x  ,y+1,steps+1));
}

int mmd_down(int h, int w, int g[h][w], int x, int y, int steps)
{
    if (base_case(h,w,x,y)) return 0;
    putchar('D');
    return max4(g[x][y]?steps:0,
           mmd_down (h,w,g,x+1,y  ,steps+1),
           mmd_left (h,w,g,x  ,y-1,steps+1),
           mmd_right(h,w,g,x  ,y+1,steps+1));
}

int mmd_left(int h, int w, int g[h][w], int x, int y, int steps)
{
    if (base_case(h,w,x,y)) return 0;
    putchar('L');
    return max2(g[x][y]?steps:0,
           mmd_left (h,w,g,x  ,y-1,steps+1));
}

int mmd_right(int h, int w, int g[h][w], int x, int y, int steps)
{
    if (base_case(h,w,x,y)) return 0;
    putchar('R');
    return max2(g[x][y]?steps:0,
           mmd_right(h,w,g,x  ,y+1,steps+1));
}

Utility Functions

int base_case(int h, int w, int x, int y)
{
    if (x < 0) return 1;
    if (y < 0) return 1;
    if (x >= h) return 1;
    if (y >= w) return 1;
    return 0;
}

int max2(int a, int b)
{
    return ((a > b) ? a : b);
}

int max4(int a, int b, int c, int d)
{
    int m = a;
    if (b > m) m = b;
    if (c > m) m = c;
    if (d > m) m = d;
    return m;
}

int max8(int a, int b, int c, int d, int e, int f, int g, int h)
{
    int m = a;
    if (b > m) m = b;
    if (c > m) m = c;
    if (d > m) m = d;
    if (e > m) m = e;
    if (f > m) m = f;
    if (g > m) m = g;
    if (h > m) m = h;
    return m;
}
Khaled.K
  • 5,828
  • 1
  • 33
  • 51