poj 2488 A Knight's Journey 【骑士周游 dfs + 记忆路径】

题目地址:http://poj.org/problem?id=2488

Sample Input

3
1 1
2 3
4 3

Sample Output

Scenario #1:
A1

Scenario #2:
impossible

Scenario #3:
A1B3C1A2B4C2A3B1C3A4B2C4

//img-my.csdn.net/uploads/201107/30/0_1312045975wCTo.gif


题目:给你一个p*q的棋盘,规则布局参考上图。列用字母表示,行用数字表示。这样一个左上角的节点就是(A,1)。
骑士的棋子走日字形状,可以从任意节点出发,终点也是任意的。问你能不能遍历所有的位置,并输出这样的路径,如果
存在多条路径,输出字典序最小的那条路径。
分析:按照上面那个图片的提示,从当前位置出发遍历8个方向,如果最后能到达,得到的就是字典序最小的序列。
起点一定会是(A1)。直接从A1开始dfs。
通过这道题,再次体会到回溯的地方。。。。。。
code:
#include<stdio.h>
#include<string.h>
#include <queue>
#include <stack>
#include <algorithm>
#define Max 21

using namespace std;

int n, m;
bool vis[30][30];
int x[]={-1, 1, -2, 2,-2, 2,-1, 1};
int y[]={-2,-2, -1,-1, 1, 1, 2, 2};
//从当前马的位置可以走到的8个位置
//在满足字典序最小的前提下 这8个方向的遍历先后不能变动
bool ok;

struct node
{
    int col, row;
}path[1000];
int e=0;

bool sure(int i, int j)
{
    if(i>=1 && i<=n && j>=1 && j<=m)
        return true;
    else
        return false;
}

void dfs(int i, int j, int cnt)//cnt表示我们在当前这次dfs偶中搜索到的节点
{
    path[cnt].col=j; path[cnt].row=i;//当前位置进入路径队列

    if(cnt==n*m){
        ok=true; return; //所有节点都已经遍历到
    }//在这return 开始往回回溯

    int a, b;
    for(int k=0; k<8; k++){

        a=i+x[k];
        b=j+y[k];
        if(sure(a, b) && !vis[a][b]){
            vis[a][b]=true;
            dfs(a, b, cnt+1);
            if(ok==true) return;//在这return 返回主函数
            vis[a][b]=false;
        }
    }
    return;
}

int main()
{
    int tg; scanf("%d", &tg);
    int cnt=1;

    while(tg--)
    {
        scanf("%d %d", &n, &m);
        ok=false;
        if(n==1 && m==1){
            printf("Scenario #%d:\n", cnt++);
            printf("A1\n\n");
            continue;
        }
        else{
            ok=false;
            memset(vis, false, sizeof(vis));
            vis[1][1]=true;
            e=0;
            dfs(1, 1, 1);

            if(!ok){
                printf("Scenario #%d:\n", cnt++);
                printf("impossible\n\n");
            }
            else{
                printf("Scenario #%d:\n", cnt++);
                for(int i=1; i<=n*m; i++)
                {
                    printf("%c%d", path[i].col+'A'-1, path[i].row );
                }
                printf("\n\n");
            }
        }
    }
	return 0;
}

 


posted @ 2015-08-22 16:29  我喜欢旅行  阅读(1108)  评论(0编辑  收藏  举报