poj 2488

DFS

大致题意:

给出一个国际棋盘的大小,判断马能否不重复的走过所有格,并记录下其中按字典序排列的第一种路径。

经典的“骑士游历”问题,DFS水题一道

 

 

解题思路:

难度不大,但要注意的地方有3点:

 

1、  题目要求以"lexicographically"方式输出,也就是字典序...要以字典序输出路径,那么搜索的方向(我的程序是path()函数)就要以特殊的顺序排列了...这样只要每次从dfs(A,1)开始搜索,第一个成功遍历的路径一定是以字典序排列...

下图是搜索的次序,马的位置为当前位置,序号格为测试下一步的位置的测试先后顺序

按这个顺序测试,那么第一次成功周游的顺序就是字典序


 

2、国际象棋的棋盘,行为数字p;列为字母q

3、网上有同学说 这道题最后一组数据后是有空行的会PE...,我测试过,不会的,能AC


#include <iostream>
#include <string.h>
#include <vector>
#include <queue>
#include <stdio.h>
#include <cstdlib>
using namespace std;
class location
{
public:
    int row;
    char col;
};
int p,q;//p是行,q是列
bool chess['Z'+1][27];
int x,y;//返回值
void path(int i,int j,int num)//i,j为当前位置,num为要跳到的位置序号,有8种跳的方式
{
    switch(num)
    {
     	case 1: {x=i-1; y=j-2; break;}     //按照字典序
		case 2: {x=i+1; y=j-2; break;}
		case 3: {x=i-2; y=j-1; break;}
		case 4: {x=i+2; y=j-1; break;}
		case 5: {x=i-2; y=j+1; break;}
		case 6: {x=i+2; y=j+1; break;}
		case 7: {x=i-1; y=j+2; break;}
		case 8: {x=i+1; y=j+2; break;}
    }
    return;
}
bool DFS(location* way,int i,int j,int step)
{
    chess[i][j]=true;
    way[step].row=i;
    way[step].col=j;
    if(step==way[0].row)
        return true;
    for(int k=1;k<=8;k++)
    {
        path(i,j,k);
        int ii=x,jj=y;
        if(!chess[ii][jj]&&ii>=1&&ii<=p&&jj>='A'&&jj<='A'+q-1)
            if(DFS(way,ii,jj,step+1))
                return true;
    }
    chess[i][j]=false;
    return false;
}
int main()
{
    int test;
    cin>>test;
    int t=1;
    while(t<=test)
    {
        memset(chess,false,sizeof(chess));
        cin>>p>>q;
        location* way=new location[p*q+1];
        way[0].row=p*q;
        bool flag=false;

                if(DFS(way,1,'A',1))
                {
                    cout<<"Scenario #"<<t++<<':'<<endl;
                    for(int k=1;k<=way[0].row;k++)
                        cout<<way[k].col<<way[k].row;
                    cout<<endl<<endl;
                    flag=true;
                    continue;
                }

        if(!flag)
        {
            cout<<"Scenario #"<<t++<<':'<<endl;
            cout<<"impossible"<<endl<<endl;
        }
    }
    system("pause");
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值