POJ 2488


转载请注明出处:優 YoU  http://user.qzone.qq.com/289065406/blog/1303350143 

大致题意:

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

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

 

 

解题思路:

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

 

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

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

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


 

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

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







//Memory Time 
//240K   32MS 

#include
  
  
   
   
using namespace std;

typedef class
{
	public:
		int row;
		char col;
}location;

int p,q;  //chess size = p*q
          //数字是行p,字母是列q
bool chess['Z'+1][27];

int x,y;  //返回值
void path(int i,int j,int num)  //ij为骑士当前在棋盘的位置 
{                               //num为骑士即将要跳到的位置序号
	switch(num)
	{
     	case 1: {x=i-1; y=j-2; break;}     //注意这个尝试跳的顺序不能错   
		case 2: {x=i+1; y=j-2; break;}     //因为题目要求是字典序lexicographically输出
		case 3: {x=i-2; y=j-1; break;}     //这个顺序错了,必定WA
		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;  //能执行到这步,说明前面跳的8步都不符合要求
	return false;       //即当前位置是错误位置,擦除记录返回上一步
}

int main(void)
{
	int test;
	cin>>test;
	int t=1;
	while(t<=test)
	{
		/*Initial*/

		memset(chess,false,sizeof(chess));

		cin>>p>>q;
		if(p==1 && q==1)      //范围缩窄,不要也能AC
		{
			cout<<"Scenario #"<
   
   
    
    <<':'<
    
    
     
     26 || p>=9 || q>=9 || p<=2 || q<=2)        //范围缩窄,不要也能AC
		{
			cout<<"Scenario #"<
     
     
      
      <<':'<
      
      
     
     
    
    
   
   
  
  

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值