方格遍历问题

问题提出

 

每天在物理楼乘电梯之前要等一会,我就在门口踱步,地上是很多地板方格。我从某一个方格开始,只是上下左右移动,又不想踩到已经踩过的方格,所以只能选择一条路径,使得能从start方格到end方格,又能遍历所有的方格,同时每一个方格只能访问一次。

 

例子

 

有路径


 

没有路径


 

一个简单的程序:

 

//give start and end, find the path and DFS visit the all the cells of sqaure grid

//xiangge

 

#include <iostream>

 

using std::cout;

using std::endl;

 

class Grid{

public:

    Grid(int sizex, int sizey): sizex(sizex), sizey(sizey), size(sizex*sizey), nLeft(size)

    {

        mat = new bool[size];

        for(int i=0; i<size; i++)

            mat[i] = false;

        path = new int[size];

    }

    ~Grid(){delete [] mat; delete [] path;}

    bool DFS_visit(int startx, int starty, int endx, int endy);

    void printPath(int startx, int starty, int endx, int endy);

    void clear();

private:

    int sizex;

    int sizey;

    int size;

    int nLeft;

    bool* mat;

    int* path; //path as 1,2,3,...

};

 

//if no path, return false; else true, and print path

bool Grid::DFS_visit(int startx, int starty, int endx, int endy)

{

    int mark = startx*sizex+starty;

    if(startx<0 || startx>=sizex || starty<0 || starty>=sizey || mat[mark]==true)

        return false;

    if(startx==endx && starty==endy)

    {

        if(nLeft<=1) //last cell

        {

            nLeft--;

            mat[mark] = true;

            path[mark] = size-nLeft; //Step No.

            return true;

        }

        else

        {

            return false;

        }

    }

    nLeft--;

    mat[mark] = true;

    path[mark] = size-nLeft; //Step No.

    if(DFS_visit(startx-1, starty, endx, endy)) return true;

    else if(DFS_visit(startx+1, starty, endx, endy)) return true;

    else if(DFS_visit(startx, starty-1, endx, endy)) return true;

    else if(DFS_visit(startx, starty+1, endx, endy)) return true;

    

    nLeft++;

    mat[mark] = false;

    return false;

}

 

void Grid::printPath(int startx, int starty, int endx, int endy)

{

    for(int i=0; i<sizex; i++)

    {

        for(int j=0; j<sizey; j++)

        {

            if(i==startx && j==starty)

                printf(" sta ");

            else if(i==endx && j==endy)

                printf(" end ");

            else

                printf("%d   ", path[i*sizey+j]);

        }

        printf("\n");

    }

}

 

void Grid::clear()

   

    for(int i=0; i<size; i++)

    {

        mat[i] = false;

        path[i] = 0;

    }

    nLeft=size;

}

 

int main()

{

    Grid g(4, 4);

    if(!g.DFS_visit(1, 3, 2, 1))

        printf("No Path!\n");

    g.printPath(1, 3, 2, 1);

 

    g.clear();

    if(!g.DFS_visit(1, 3, 2, 2))

        printf("No Path!\n");

    g.clear();

    g.printPath(1, 3, 2, 2);

    system("pause");

}

 

 


原文地址:http://blog.sina.com.cn/s/blog_679f93560100xz2c.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值