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

本文介绍了一种解决骑士周游问题的算法,通过设定棋盘大小、障碍物位置及数量,采用特定策略寻找从任意起点出发遍历整个棋盘的路径。算法考虑了障碍物对马行走的影响,确保每一步都有效且不重复访问已访问过的位置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 代码如下:

#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;
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值