小灶第二次作业

第一道bfs : poj3984

http://poj.org/problem?id=3984

一个迷宫,其中的1表示墙壁,0表示可以走的路,只能横着走或竖着走,不能斜着走,要求编程序找出从左上角到右下角的最短路线。


第一个问题是如何记录路径,因为不想用结构体记录,所以想到在重新开一个数组,把每一步的上一部记录下来,这样,反过头来就可以找到了,由于bfs是用队列实现的,第一次写的时候自作聪明的用了queue(stl),然后悲剧的发现不能保存二维坐标,于是,重新开始自己写了队列(第一次写,head 和tail 的赋值上各种崩溃,要注意每次tail的++位置,以及初始值给0,1的问题),队列也开了二维数组 ,第二维开了【2】,代表x 和y,然后开了pre数组,本来想直接开二维数组做成地图就可以了,但是由于还是要在一个里面保存横纵坐标,还是做不到啊,只好尝试了开第三维(同第一次),同样代表x,y,输出时要倒过来,第一想法就是递归,于是写了print函数,后来被告知。。。可以用栈,反正也没写过,就试了一下,两个代码都ac了。


栈输出:

#include 
#include 


using namespace std;
bool a[5][5];
int book [5][5];
int next [4][2] = { {0,1},{0,-1},{1,0},{-1,0} };
int pre[5][5][2];
int queue[120][2];
int stack[100][2];


int main()
{
    for (int i = 0 ; i < 5 ; i++)
        for (int j = 0  ; j < 5 ; j++)
        {
            scanf("%d,",&a[i][j]);


        }


    int i = 0 , j = 0 ;
    int head = 0 ,flag = 0,tail = 1,xa,xb;
    queue[head][0] = i;
    queue[head][1] = j;
    book[0][0] = 1;
    int l = 0;


    while (head < tail)
    {
        for (int k = 0 ; k < 4 ; k++)
        {
            xa = i + next[k][0];
            xb = j + next[k][1];
            if(xa >= 0 && xa < 5 && xb >= 0 && xb < 5 && !a[xa][xb] && !book [xa][xb])
            {
                book[xa][xb] = 1;
                pre[xa][xb][0] = i;
                pre[xa][xb][1] = j;




                if(xa == 4 && xb == 4)
                  {
                      flag = 1;
                      break;
                  }
               queue[tail][0] = xa;
               queue[tail++][1] = xb;
            }
        }
        head++;
        if(flag)
            break;
        i = queue[head][0];
        j = queue[head][1];


    }
    i = 4 ; j = 4;
    int x = 4 , y = 4;
    stack[l][0] = i;
    stack[l++][1] = j;
     //print (i ,j);
     while (1)
     {
         if(x == 0 && y == 0)
            break;
         stack[l][0] = pre[i][j][0];
         stack[l++][1] = pre[i][j][1];
         x = pre[i][j][0];
         y = pre[i][j][1];
         i = x;
         j = y;
     }


     for (int p = l - 1 ; p >= 0;p--)
        printf("(%d, %d)\n",stack[p][0],stack[p][1]);


    return 0;
}


-------------------------------------------------------------------------------

递归输出:

#include 
#include 

using namespace std;
bool a[5][5];
int book [5][5];
int next [4][2] = { {0,1},{0,-1},{1,0},{-1,0} };
int pre[5][5][2];
int queue[120][2];

void print(int i , int j)
{
    if (i == 0 && j == 0)
        {
            printf("(0, 0)\n");
            return ;
        }
    print(pre[i][j][0],pre[i][j][1]);
    printf("(%d, %d)\n",i ,j);
    return ;
}

int main()
{
    for (int i = 0 ; i < 5 ; i++)
        for (int j = 0  ; j < 5 ; j++)
        {
            scanf("%d,",&a[i][j]);
//            queue[i * 5 + j][0] = i;
//            queue[i * 5 + j][1] = j;
        }

    int i = 0 , j = 0 ;
    int head = 0 ,flag = 0,tail = 1,xa,xb;
    queue[head][0] = i;
    queue[head][1] = j;
    book[0][0] = 1;

    while (head < tail)
    {
        for (int k = 0 ; k < 4 ; k++)
        {
            xa = i + next[k][0];
            xb = j + next[k][1];
            if(xa >= 0 && xa < 5 && xb >= 0 && xb < 5 && !a[xa][xb] && !book [xa][xb])
            {
                book[xa][xb] = 1;
                pre[xa][xb][0] = i;
                pre[xa][xb][1] = j;


                if(xa == 4 && xb == 4)
                  {
                      flag = 1;
                      break;
                  }
               queue[tail][0] = xa;
               queue[tail++][1] = xb;
            }
           //tail++;
        }
        head++;
        if(flag)
            break;
        i = queue[head][0];
        j = queue[head][1];
       // printf("%d  %d\n",i,j);

    }
    i = 4 ; j = 4;
     print (i ,j);

    return 0;
}

你可能感兴趣的:(acm,小灶作业)