POJ 2488 A Knight's Journey

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

题意:给一个p*q的棋盘,输出一个字典序最优的骑士遍历路径。

解法:

显然一道深搜,但恶心就恶心在字典序。

行row表示数字,列col表示字母,依照字典序先遍历col再遍历row。

骑士每步可走八个方位,在path()中给出。

#include<iostream>
using namespace std;

int x,y,p,q;
bool vis[30][30];

struct pos
{
       int  r;
       char c;
};

pos *way;

void path(int r,int c,int num)
{
     switch(num)
     {
       case 1:x=r-1;y=c-2;break;
       case 2:x=r+1;y=c-2;break;
       case 3:x=r-2;y=c-1;break;
       case 4:x=r+2;y=c-1;break;
       case 5:x=r-2;y=c+1;break;
       case 6:x=r+2;y=c+1;break;
       case 7:x=r-1;y=c+2;break;
       case 8:x=r+1;y=c+2;break;
     }
     return ;
}

bool dfs(pos *way,int i,int j,int step)
{
     vis[i][j]=1;
     way[step].r=i;
     way[step].c=char('A'+j-1);
     if(step==p*q) return 1;
     for(int k=1;k<=8;k++)
     {
             path(i,j,k);
             int r=x,c=y;
             if(r>0&&r<=p&&c>0&&c<=q&&!vis[r][c])
                if(dfs(way,r,c,step+1))
                return 1;
             
     }
     vis[i][j]=0;
     return 0;
}




int main()
{
    int n;
    bool flag;
    while(cin>>n)
    {
      for(int t=1;t<=n;t++)
      {
        cin>>p>>q;
        flag=0;
        memset(vis,0,sizeof(vis));
        way=new pos[p*q+1];
        way[0].r=p*q;
        for(int j=1;j<=q;j++)                    //输出是字典序 
           {                                     //先遍历列(字母) 
                for(int i=1;i<=p;i++)            //再遍历行(数字) 
                {
                    if(dfs(way,i,j,1))
                    {
                      flag=1;
                      break;
                    }     
                }
                if(flag) break;
           }
        cout<<"Scenario #"<<t<<':'<<endl; 
        if(flag)
        {
          for(int i=1;i<=p*q;i++)
          cout<<way[i].c<<way[i].r;
          cout<<endl<<endl;

        }
        else
        cout<<"impossible"<<endl<<endl;
      }
    }
    return 0;
}


你可能感兴趣的:(搜索,poj,poj,poj)