递归,搜索,回溯,最优路径(线段)

基本信息 内存:520kB 时间:0ms 语言:G++

题目链接http://bailian.openjudge.cn/practice/solution/4779752/

解题报告:

1、输入表格时,由于这里有空格,不能用scanf函数。

2、gets(board[i]+1) 不要把第一列刷去。

3、回溯mark[y][x]=false;这里在Search玩后,一定要将mark[y][x]改为false.否则下一次的搜索将不会访问到这个点。

4、方向最好用数组形式表示。

5、最重要的一点是:这里的一条线段才为一步,因此,face于是记录方向。

#include <stdio.h>
#include <string.h>

#define MAXIN 75
#define INF 0x3f3f3f3f

#define IN_BOARD ((x > -1) && (x < w + 2) && (y>-1) && (y<h + 2))    //x,y在边界内
#define BLANK_POINT ((board[y][x] == ' ') && (mark[y][x] == false))    //该点为空
#define DESTINATION ((x ==end_x) && (y ==end_y) && (board[y][x] == 'X'))    //达到目的地

char board[MAXIN + 2][MAXIN + 2];//定义矩阵
int minstep, w, h;
int to[4][2] = { { 0,1 },{ 0,-1 },{ 1,0 },{ -1,0 } };
bool mark[MAXIN + 2][MAXIN + 2];

void Search(int now_x, int now_y, int end_x, int end_y, int step, int face)
{
    if (step > minstep)    return;

    if (now_x == end_x && now_y == end_y)
        {
            if(minstep>step)
            minstep = step;
            return;
        }

    for (int i = 0; i < 4; i++)
    {
        int x = now_x + to[i][0];
        int y = now_y + to[i][1];
        if (IN_BOARD && (BLANK_POINT || DESTINATION))
        {
            mark[y][x] = true;
            if (face == i) Search(x, y, end_x, end_y, step, i);
            else Search(x, y, end_x, end_y, step + 1, i);
            mark[y][x] = false;
        }
    }
}

int main()
{
    int BoardNum = 0;
    while (scanf("%d%d", &w, &h))
    {
        getchar();
        if (w == 0 && h == 0) break;
        printf("Board #%d:\n", ++BoardNum);

        for (int i = 1; i <= h; i++)
            gets(board[i]+1);

        //边界置空
        for (int i = 0; i <= w + 1; i++)
            board[0][i] = board[h + 1][i] = ' ';
        for (int i = 0; i <= h ; i++)
            board[i][0] = board[i][w + 1] = ' ';


        int begin_x, begin_y, end_x, end_y;
        int count = 0;
        while (scanf("%d%d%d%d", &begin_x, &begin_y, &end_x, &end_y) && begin_x > 0)
        {
            minstep = INF;
            memset(mark, false, sizeof(mark));

            Search(begin_x, begin_y, end_x, end_y, 0, -1);

            if (minstep < INF)
                printf("Pair %d: %d segments.\n", ++count, minstep);
            else
                printf("Pair %d: impossible.\n", ++count);
        }
        printf("\n");
    }
    return 0;
}

 

你可能感兴趣的:(递归,搜索,回溯,最优路径(线段))