贪心算法解决马的遍历(带蹩马腿)

 代码如下:

#pragma once
#include<stdlib.h>
#include<stdio.h>
#include <iostream>


#define MAXV 6																 /*棋盘大小*/
#define cross(x,y)		((x) < 0 || (x) >= MAXV || (y) < 0 || (y) >= MAXV)	 /*判定是否越界*/
#define obstruct(x,y)	(map[(x)-1][(y)] == 2 && map[(x)+1][(y)] == 2 && \
						 map[(x)][(y)-1] == 2 && map[(x)][(y)+1] == 2)		 /*判定是否陷入死胡同*/
extern int step[8][2];														 /*存放马前进的方向*/

/*************************************************
Function:
	Init()
Description:
	initialize the map array
Called By:
	main();
Input:
	int map[MAXV][MAXV]: the map array
Output:
	int map[MAXV][MAXV]: the map array
	int obs: the number of obstacle
*************************************************/
int Init(int map[MAXV][MAXV])
{
	int i, j;
	int obs = 0;						//蹩马腿的棋子数量
	char choose;
	int x, y;							//蹩马腿棋子坐标
	int obsX[MAXV] = { 0 }, obsY[MAXV] = {0};
	bool loop = true;
	for (i = 0; i < MAXV; i++)
	{
		for (j = 0; j < MAXV; j++)
		{
			map[i][j] = 0;
		}
	}
	while (loop)
	{
		printf("是否设置蹩马腿棋子(y/n):");
		scanf("%s", &choose);
		loop = false;
		if (choose == 'y')
		{
			printf("\n请输入蹩马腿棋子数量(0<x<%d):", MAXV);
			scanf("%d", &obs);
			for (i = 0; i < obs; i++)
			{
				printf("请输入第%d个棋子的x坐标(0≤x<%d):",i + 1, MAXV);
				scanf("%d", &x);
				obsX[i] = x;
				printf("请输入第%d个棋子的y坐标(0≤y<%d):",i + 1, MAXV);
				scanf("%d", &y);
				obsY[i] = y;
				map[x][y] = 2;
			}
			printf("\n蹩马腿棋子坐标为:\n");
			for (i = 0; i < obs; i++)
			{
				printf("(%d, %d)\t", obsX[i], obsY[i]);
			}
		}
		else if (choose == 'n')
		{
			obs = 0;
		}
		else
		{
			printf("请输入正确的选项!\n");
			loop = true;
		}
	}

	return obs;
}


/*************************************************
Function:
	Isobs()
Description:
	judge whether the next step is available
Called By:
	Entrance();
Input:
	int x: the x-coordinate of the current point
	int y: the y-coordinate of the current point
	int map[MAXV][MAXV]: the map array
	int index: the index of direction array
Output:
	bool step:	judge whether the next step is available
*************************************************/
bool isObs(int x, int y, int index, int map[MAXV][MAXV])
{
	if (index == 0 || index == 1)
	{
		if (map[x - 1][y] != 2 )
			return true;
	}
	else if (index == 2 || index == 3)
	{
		if (map[x][y + 1] != 2 )
			return true;
	}
	else if (index == 4 || index == 5)
	{
		if (map[x + 1][y] != 2 )
			return true;
	}
	else if (index == 6 || index == 7)
	{
		if (map[x][y - 1] != 2 )
			return true;
	}
	else
		return false;
}



/*************************************************
Function: 
	Entrance()
Description: 
	record the number of entrance
Called By: 
	Next()
Input:
	int x: the x-coordinate of the current point
	int y: the y-coordinate of the current point
	int dir[]: recoder the index of entrances
	int map[MAXV][MAXV]: the map array
Output: 
	int count: the number of entrances
	int dir[]: recoder the index of entrances
*************************************************/
int Entrance(int x, int y, int dir[], int map[MAXV][MAXV])
{
	int i;				
	int stepX, stepY;				//下一方向x,y位移
	int count=0;						//记录可走出口数
	bool obs;
	bool cros;
	for (i = 0; i < 8; i++)
	{
		stepX = x + step[i][0];
		stepY = y + step[i][1];		//下一方向坐标
		obs = isObs(x, y, i, map);
		cros = !cross(stepX, stepY);

		if (cros && map[stepX][stepY] == 0 && obs)			//坐标未越界且可走时
		{
			
			dir[count] = i;														//记录可走出口索引
			count += 1;
		}
	}
	return count;
}


/*************************************************
Function: 
	Next()
Description: 
	find the index of the next step
Called By: 
	main()
Input:
	int x: the x-coordinate of the current point
	int y: the y-coordinate of the current point
	int dir[]: recoder the index of entrances
	int map[MAXV][MAXV]: the map array
Output: 
	int index: the index of the next step 
*************************************************/
int  Next(int x, int y,int dir[], int map[MAXV][MAXV])
{	
	int count;									//当前坐标的出口数
	int stepX, stepY;							//下一步坐标
	int min = 8;								//最少入口数
	int nextCount;								//下一步入口数
	int nextDir[8] = { 0 };
	int index = 0;									//最终下一步索引
	count = Entrance(x, y, dir, map);

	if (count == 0)								//没有出口则返回-1
		return -1;
	for (int i = 0; i < count; i++)
	{
		stepX = x + step[dir[i]][0];			
		stepY = y + step[dir[i]][1];
		nextCount = Entrance(stepX, stepY, nextDir, map);
		if ( nextCount < min)	//找出出口数最少的下一步索引
		{
			min = nextCount;
			index = dir[i];
		}
	}
	return index;
}

/*************************************************
Function: 
	Travel()
Description:
	Travel the chessboard and input the path
Called By:
	main()
Input: 
	int x: the x-coordinate of the start point
	int y: the y-coordinate of the start point
	int obs: the number of obstacle
	int map[MAXV][MAXV]: the map array
Output: 
	the path of traveling
*************************************************/
void Travel(int x, int y, int obs, int map[MAXV][MAXV])
{
	int pathX[MAXV*MAXV + 1];				//遍历路径
	int pathY[MAXV*MAXV + 1];
	for (int i = 0; i < MAXV*MAXV + 1; i++)
	{
		pathX[i] = -1;				//遍历路径
		pathY[i] = -1;
	}
	map[x][y] = 1;							//起点置1
	pathX[0] = x;
	pathY[0] = y;
	int cal = 0;							//遍历点数
	int dir[8];								//存放方向索引
	bool conti = true;
	int index;
	int mount = MAXV * MAXV - obs;				//完全遍历总步数

	int i = 0 ,n = 0;
	int len = 1;
	while (i < mount && !obstruct(x, y))
	{
		index = Next(x, y, dir, map);
		if (index != -1)
		{
			x = x + step[index][0];
			y = y + step[index][1];
			pathX[len] = x;
			pathY[len] = y;
			if(map[x][y] != 2)
				map[x][y] = 1;
			len += 1;
		}
		i += 1;

	}
	printf("\n路径长度为:%d\n", len);
	printf("起点(%d, %d)到终点(%d, %d)的路径为:\n", pathX[0], pathY[0],pathX[len], pathY[len]);
	while (pathX[n] != -1 && pathY[n] != -1) 
	{
		printf("(%d, %d)\t", pathX[n], pathY[n]);
		if (n % 5 == 4)
		{
			printf("\n");
		}
		n += 1;
	}
	printf("\n\n");
}



/* The values of the array represent*/
/* whether the node was visited, as follows */
/* 0 - Access   1- Access	Forbidden*/
/* only function DFS() in this*/
/* modual can modify and visit it*/
int visited[MAXV] = { 0 };

/* The values of the array represent*/
/* the direction that horse will go */
int step[8][2] = { {-2,-1},{-2,1},{-1,2},{1,2},{2,1},{2,-1},{1,-2},{-1,-2} };


int main()
{
	int x, y;					//起点坐标
	int conti = true;
	int obs;					//蹩马腿数量
	while (conti)
	{
		conti = false;
		printf("请输入起点的x坐标(0≤x<%d):", MAXV);
		scanf("%d", &x);
		printf("请输入起点的y坐标(0≤y<%d):", MAXV);
		scanf("%d", &y);
		if (x < 0 || x >= MAXV || y < 0 || y >= MAXV)
		{
			printf("\n请重新输入正确的坐标!\n\n");
			conti = true;
		}
	}

	int map[MAXV][MAXV];
	obs = Init(map);
	Travel(x, y,obs,map);
	system("pause");
	return 0;
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
运 用 贪 心 算 法 ,vc++ 语 言 编 写 , 可 单 步 输 出 结 果 【问题描述】 跳问题也称骑士遍历踏棋盘问题:在8*8方格的棋盘上,从任意指定的方格出发,为象棋中的寻找一条走遍棋盘每一格并且只经过一次的一条路径。 考虑国际象棋棋盘上某个位置的一只,它是否可能只走63步,正好走过除起点外的其他63个位置各一次?如果有一种这样的走法,则称所走的这条路线为一条的周游路线。试设计一个算法找出这样一条的周游路线。 在一个8×8的方格棋盘中,按照国际象棋中的行走规则从棋盘上的某一方格出发,开始在棋盘上周游,如果能不重复地走遍棋盘上的每一个方格, 这样的一条周游路线在数学上被称为国际象棋盘上的哈密尔顿链。请你设计一个程序,从键盘输入一个起始方格的坐标,由计算机自动寻找并打印 【算法描述】 本题有较多方法求解,在此仅对回溯法进行分析。 一只在棋盘的某一点,它可以朝8个方向前进,方向向量分别是:(2,1)、(2,-1)、(1,2)、(1,-2)、(-2,1)、(-2,-1)、(-1,2)、(-1,-2)。从中任选择一个方向前进,到达新的位置。在从新的位置选择一个方向前进,继续,直到无法前进为止。无法前进可能有如下原因:下一位置超出边界、下一位置已经被访问过。当已经无法前进时,就回退到上一位置,从新选择一个新的方向前进;如果还是无法前进,就再回退到上一位置……

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值