POJ2248 A Knight's Journey(DFS)

题目链接

题目大意:

给定一个矩阵,马的初始位置在(0,0),要求给出一个方案,使马走遍所有的点。

列为数字,行为字母,搜索按字典序。

 

分析:

用 vis[x][y] 标记是否已经访问。因为要搜索所有的可能,所以没搜索完一次要把vis[x][y]标记为未访问。详情见代码。

用 p[x][y] 表示 (x,y)点的祖先,以便输出路径。

dfs搜索即可。

 

#include <iostream>
#include <cstdio>
#include <string>
#include <map>
#include <cstring>

using namespace std;

const int maxn = 30;
const int VAL = 10000;

int dx[] = {-1, 1, -2, 2, -2, 2, -1, 1};    //搜索顺序是字典序
int dy[] = {-2, -2, -1, -1, 1, 1, 2, 2};

bool vis[maxn][maxn];
int p[maxn][maxn], ex, ey;
int cnt, total, n, m;

bool dfs(int x, int y, int px, int py) {
    p[x][y] = px*VAL+py;

    cnt++;

    //如果已经走遍的点等于总点数,表示已经全部访问完
    if(cnt == total) {
        ex = x; ey = y;
        return true;
    }

    for(int d=0; d<8; d++) {
        int nx = x+dx[d];
        int ny = y+dy[d];

        if(nx < 0 || ny < 0 || nx >= n || ny >= m) continue;
        if(vis[nx][ny]) continue;

        vis[nx][ny] = true; //标记已访问

        if(dfs(nx, ny, x, y)) return true;

        vis[nx][ny] = false;    //标记未访问
        cnt--;  //已访问的数要减一
    }

    return false;
}

void print(int x, int y) {
    if(x == 0 && y == 0) return;
    int e = p[x][y];
    int px = e/VAL, py = e%VAL;
    print(px, py);
    printf("%c%d", y+'A', x+1); //y对应字母,x对应数字
}

int main(){
    int T;
    scanf("%d", &T);
    for(int kase=1; kase<=T; kase++) {
        scanf("%d%d", &n, &m);
        cnt = 0; total = n*m;

        memset(vis, 0, sizeof(vis));

        vis[0][0] = true;

        printf("Scenario #%d:\n", kase);

        if(dfs(0, 0, 0, 0)) {   //有方案,输出
            printf("A1");
            print(ex, ey);
            putchar('\n');
        }
        else printf("impossible\n");
        putchar('\n');
    }

    return 0;
}

 

 

posted on 2013-07-29 19:06  Still_Raining  阅读(233)  评论(0编辑  收藏  举报