经典算法---骑士走棋盘

20 篇文章 0 订阅
17 篇文章 0 订阅
骑士走棋盘 

#define SIZE 8

int possible(int board[][SIZE],int nexti[],int nextj[],int x,int y);

int min_direction(int board[][SIZE],int nexti[],int nextj[],int count);


bool travel(int board[][SIZE],int x,int y)
{
	int nexti[SIZE] = {0};
	int nextj[SIZE] = {0};//记录下一跳的位置信息

	int i = x;
	int j = y;

	board[i][j] = 1;//标记第一个点访问

	int MAX = SIZE*SIZE;
	int count = 0;//

	for(int m=2;m<=MAX;m++)
	{
		count=possible(board,nexti,nextj,i,j);//得到可能的下一跳数目  ,其中nexti[],nextj[]中记录了下一跳的跳法

		if(count==0)
			return false;    //无可走方向,遍历失败  

		int min_Direction=min_direction(board,nexti,nextj,count);//在多个可能方向中查找下一跳方向最少的方向  
		i=nexti[min_Direction];      //下一跳位置坐标  
		j=nextj[min_Direction];  

		board[i][j]=m;               //当前位置为第m次走的位置  
	}

	return true;
}

int possible(int board[][SIZE],int nexti[],int nextj[],int x,int y)
{
	int mvi[SIZE]={-2,-1,1,2,2,1,-1,-2};    //下一跳可能的八个方向(x坐标y坐标)  
	int mvj[SIZE]={1,2,2,1,-1,-2,-2,-1};  
	int count=0;  

	for(int i=0;i<SIZE;++i) //依次遍历8个方向
	{  
		int tmpx=x+mvi[i];  
		int tmpy=y+mvj[i];  //计算移动后的位置信息

		if(tmpx<0||tmpy<0||tmpx>SIZE-1||tmpy>SIZE-1)
			continue; //越界,不是可行方向  
		if(board[tmpx][tmpy]==0)                  //未走过,找到一个可能方向  
		{  
			nexti[count]=tmpx;  
			nextj[count]=tmpy;  
			count++;  
		}  
	}  
	return count;  //返回可能的下一跳的数目
}

void printBoard(int board[][SIZE],FILE *fp_out)
{
	for(int i=0;i<SIZE;i++)
	{
		for(int j=0;j<SIZE;j++)
		{
			cout<<board[i][j]<<" ";
			fprintf(fp_out,"%d ",board[i][j]);
		}
			
		fprintf(fp_out,"%s","\n");
		cout<<endl;
	}

	fprintf(fp_out,"%s","\n \n");
}

//计算可能下一跳中下一跳中数目最少的跳法
int min_direction(int board[][SIZE],int nexti[],int nextj[],int count)
{

	int mvx[SIZE]={-2,-1,1,2,2,1,-1,-2};  
	int mvy[SIZE]={1,2,2,1,-1,-2,-2,-1};  

	int exist[SIZE]={0};                   //记录该方向的下一跳方向的数目  
	int min_direction=-1;                  //初始化最小方向数的方向  

	if(count==1)min_direction=0;           //只有一个可行方向  

	else  
	{  
		for(int i=0;i<count;++i)           //在所有可行方向中遍历  
			for(int j=0;j<SIZE;++j)        //计算每一个方向下一跳的数目  
			{  
				int tmpx=nexti[i]+mvx[j];  
				int tmpy=nextj[i]+mvy[j];  

				if(tmpx<0||tmpy<0||tmpx>SIZE-1||tmpy>SIZE-1)//判断是否越界
					continue;  

				if(board[tmpx][tmpy]==0)   
					exist[i]++;   
			}  

		int min=exist[0];                 //取其中最小数目的方向  
        min_direction=0;  
		//选出最小的跳法
		for(int i=1;i<count;++i)         
			if(exist[i]<min)  
			{  
				min=exist[i];  
				min_direction=i;  
			}  

	}//end else

	return min_direction;
}


int main()
{
	int start_u,start_v;//起始坐标

	int board[SIZE][SIZE];

	




	FILE *fp_out = NULL;

	while(scanf("%d%d",&start_u,&start_v)!=EOF)
	{
		fp_out  = fopen("F:\\Student\\result2.4.txt","a+");

		for(int i=0;i<SIZE;i++)
			for(int j=0;j<SIZE;j++)
				board[i][j] = 0;//初始化没有访问过

		if(travel(board,start_u,start_v))
		{
			cout<<"遍历成功!"<<endl;  
			
		}
		else cout<<"遍历失败!"<<endl;  	


		printBoard(board,fp_out);  
		fclose(fp_out);
	}

	return 0;
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值