http://poj.org/problem?id=2488

题意 : 给你棋盘大小,判断马能否走完棋盘上所有格子,前提是不走已经走过的格子,然后输出时按照字典序排序的第一种路径

思路 : 这个题吧,有点别扭,再加上要用字典序输出,所以就要用一点小技巧了,自己提前将能输出字典序的那个先写到数组里保存,也就是说,搜索方向要进行特殊的排列,而这样的话,只要每次找的时候从第0行第0列开始找,第一个成功走完所有的格子一定是按字典序排列的,因为只要能走完所有的格子,而字典序最小的就是左上角那个格子,所以,直接从那个开始遍历就行了,如果马是中间那个位置,那就按照那个顺序来遍历即可

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std ;
int dix[] = {-1,1,-2,2,-2,2,-1,1} ;//按照这个方向进行遍历
int diy[] = {-2,-2,-1,-1,1,1,2,2} ;
const int maxn = 69 ;
int xx[maxn],yy[maxn] ;
int mark,m,n;
int vis[maxn][maxn] ;
void dfs(int x,int y,int step)
{
    int ax,ay ;
    vis[x][y] = step ;
    if(m*n == step)
    {
        mark = 1 ;
        return ;
    }
    for(int i = 0 ; i < 8 ; i++)
    {
        ax = x+dix[i] ;
        ay = y+diy[i] ;
        if(ax>=0&&ax<m&&ay>=0&&ay<n&&!vis[ax][ay])
        {
            xx[step] = ax ;//因为要输出路径,所以要用数组保存
            yy[step] = ay ;
            dfs(ax,ay,step+1);
            if(mark)
                return;
            vis[ax][ay] = 0 ;
        }
    }
}
void Init()
{
    memset(vis,0,sizeof(vis)) ;
    memset(xx,0,sizeof(xx)) ;
    memset(yy,0,sizeof(yy)) ;
}
int main()
{
    int t;
    cin>>t;
    for(int i = 1 ; i <= t ; i ++)
    {
        cin>>m>>n;
        int step ;
        cout<<"Scenario #"<<i<<":"<<endl;
        Init() ;
        mark = 0 ;
        step = 1 ;
        xx[0] = 0 ;
        yy[0] = 0 ;
        dfs(0,0,step) ;//从(0,0)点开始遍历
        if(mark)
        {
            for(int k = 0 ; k < m*n ; k++)
                printf("%c%d",yy[k]+'A',xx[k]+1);
            cout<<endl<<endl;
        }
        if(!mark)
            cout<<"impossible"<<endl<<endl;
    }
    return 0 ;
}
View Code

 

posted on 2013-08-27 17:04  枫、  阅读(491)  评论(0编辑  收藏  举报