poj2488A Knight's Journey

/*这个题有很多方法但是我直接想到的是dfs,经典dfs的方法,思想沿用深搜的思想,控制好边界条件,主要就是一个安字典序排列的问题,这个需要规定一个特定的方向即可,如下面数组里dir的方向其他没什么了,这类题需要在脑子有一个固定的深搜的模式,虽然题可能很灵活但是用的方法不会变化太多不然怎么可能叫dfs,熟练掌握那种思维方法很重要*/
#include 
#include 
#include 
#include 

using namespace std;

int n, p, q, flag, vis[30][30], step;//n组数据,p字母个数,q数字个数,flag判断结束的标志,vis访问的标志,step判断步数是否超限
int dir[][2]= {-2,-1,-2,1,-1,-2,-1,2,1,-2,1,2,2,-1,2,1};

struct node{
    int x, y;//横纵坐标
}print[100000];

void dfs(int a, int b)//横纵坐标的下标
{
    if(step == p*q){
        flag = 1;
        return ;
    }
    for(int i = 0; i < 8; i++){
        int dx =a + dir[i][0];
        int dy =b + dir[i][1];
        if(dx > 0 && dx <= q && dy > 0 && dy <= p && !vis[dx][dy]){
            vis[dx][dy] = 1;
            print[step].x = dx;
            print[step].y = dy;
            ++step;
            dfs(dx,dy);//直接传dxdy这是更新后的,++step就不用解释了
            if(step == p*q){//这里是必须要加的很有可能直接走完的情况若不加便永远有可能走不完
                flag = 1;
                return ;
            }
            --step;
            vis[dx][dy] = 0;
        }
    }
}

int main()
{
    int m = 0;//m组数据
    while(scanf("%d", &m) != EOF){
        int test = 0;
        while(m--){
            scanf("%d%d", &p,&q);
            printf("Scenario #%d:\n", ++test);
            memset(vis, 0, sizeof(vis));
            memset(print, 0, sizeof(print));
            step = 1;
            flag = 0;
            print[0].x = print[0].y = 1;
            vis[1][1] = 1;
            dfs(1, 1);
            if(flag){
                for(int i = 0; i < step; i++){
                    printf("%c%d", (print[i].x-1)+'A', print[i].y);
                }
                cout<

你可能感兴趣的:(dfs)