A Knight's Journey POJ - 2488(DFS棋盘)

https://vjudge.net/problem/POJ-2488

1//因为符合要求的起点一定是(A,1),故字符转化为整数后从(0,0)开始搜索
2//记录父结点,递归倒序输出,输入和输出的行列位置是相反的
3//8个方向是有先后的,应按照字典序排序
4//因为测试数据较少且范围较少,不用过多剪枝;甚至于可以直接贴答案( ̄y▽, ̄)╭ 
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <list>
#include <stack>
#include <queue>
#include <deque>
#include<iomanip>
using namespace std;
int dx[] = {-1, 1,-2, 2,-2, 2,-1, 1};//方向很重要
int dy[] = {-2,-2,-1,-1, 1, 1, 2, 2};
struct P {
    int x, y;
    P(int x = 0, int y = 0): x(x), y(y) {}
};
int pr, pc;
int r, c, m;
P pre[30][30];//记录父节点
int vis[30][30];
inline bool in_border (int mx, int my) {
    return mx>=0 && mx<r && my>=0 && my<c;
}
int dfs(int x, int y, int cnt) {
    if(cnt == m) {
        pr = x, pc = y;
        return 1;
    }

    for(int i = 0; i < 8; i++) {
        int mx = x + dx[i], my = y + dy[i];
        if(in_border(mx, my) && !vis[mx][my]) {
            pre[mx][my] = P(x, y);

            vis[mx][my] = 1;
            if(dfs(mx, my, cnt+1)) return 1;
            vis[mx][my] = 0;
        }
    }
    return 0;
}
void print(int x, int y) {
    m--;
    if(m) print(pre[x][y].x, pre[x][y].y);
    printf("%c%d", y + 'A', x + 1);
    return;
}
int main() {int T; cin >> T; getchar();
    int cp = 0;
    while(T--) {
        if(cp) printf("\n");
        printf("Scenario #%d:\n", ++cp);

        cin >> r >> c; m = r * c;

        memset(vis, 0, sizeof(vis));
        vis[0][0] = 1;

        if(!dfs(0, 0, 1)) cout << "impossible" << endl;
        else {
            print(pr, pc);
            printf("\n");
        }
    }
    return 0;
}
发布了54 篇原创文章 · 获赞 43 · 访问量 1951

猜你喜欢

转载自blog.csdn.net/Jungle_st/article/details/104680468