DFS--poj 2488

来源:互联网 发布:淘宝贷款逾期 编辑:程序博客网 时间:2024/05/16 08:13

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

大致题意:给出一个p行q列的国际棋盘,马可以从任意一个格子开始走,问马能否不重复的走完所有的棋盘。如果可以,输出按字典序排列最小的路径。打印路径时,列用大写字母表示(A表示第一列),行用阿拉伯数字表示(从1开始),先输出列,再输出行。

分析:如果马可以不重复的走完所有的棋盘,那么它一定可以走到A1这个格子。所以我们只需从A1这个格子开始搜索,就能保证字典序是小的;除了这个条件,我们还要控制好马每次移动的方向,控制方向时保证字典序最小(即按照下图中格子的序号搜索)。控制好这两个条件,直接从A1开始深搜就行了。


#include <iostream>#include <deque>#include <cstring>using namespace std;int dir[8][2]={-1,-2,1,-2,-2,-1,2,-1,-2,1,2,1,-1,2,1,2};  //注意顺序int vis[8][8];int r,c;bool Judge(int x,int y){    if(vis[x][y]==0&&x>=0&&x<r&&y>=0&&y<c)        return true;    return false;}struct Node{    int x,y;};deque<Node> d;void Print(){    Node t;    cout<<"A1";    while(!d.empty())    {        t=d.front();        cout<<(char)(t.y+65)<<t.x+1;        d.pop_front();    }    cout<<endl;}bool dfs(int x,int y){    int i,j,tag=0;    for(i=0;i<r;i++)    {        for(j=0;j<c;j++)           if(vis[i][j]!=1) tag=1;        if(tag==1) break;    }     if(tag==0) return true;           //递归终止条件,表明所有全部访问过    for(i=0;i<8;i++)    {        int row=x+dir[i][0],col=y+dir[i][1];        if(Judge(row,col))        {            vis[row][col]=1;            //设为访问过            if(dfs(row,col))            {                Node t;                t.x=row;t.y=col;                d.push_front(t);        //如果DFS成功,从终点倒退到起点,故应每次应插到队首                return true;            }            else            {                vis[row][col]=0;       //DFS失败,重新设置成未访问                d.clear();             //一旦DFS失败,就清空,而不是弹出一个队列元素            }        }    }    return false;                      //路径搜索失败}int main(){    int n,i;    cin>>n;    for(i=0;i<n;i++)    {        cin>>r>>c;        vis[0][0]=1;        cout<<"Scenario #"<<i+1<<":"<<endl;        if(r==1&&c==1) cout<<"A1"<<endl;        else if(dfs(0,0)==false)            cout<<"impossible"<<endl;        else Print();        memset(vis,0,sizeof(vis));        d.clear();        if(i!=n-1)        cout<<endl;    }    return 0;}






















0 0