C语言贪心算法求解马踏棋盘问题

程序演示图

在这里插入图片描述

源程序

#include<stdio.h>
#include<stdlib.h>
#define ROW 100
#define COL 100

int chess[ROW][COL]={0};
int row;
int col;
int x,y;
int min;
int turn[][2]={{1,2},{1,-2},{-1,2},{-1,-2},{2,1},{2,-1},{-2,1},{-2,-1}};
int max;
int result;

typedef struct direct	//方向 
{
	int count;			//可能
	int index;			//下标 
}Direct;

//确定地图
void input()
{
	printf("行:");
	scanf("%d",&row);
	printf("列:");
	scanf("%d",&col);
	printf("起始坐标(x,y):");
	scanf("%d %d",&x,&y);
	x+=2;
	y+=2;
} 

//初始化 
void init()
{
	int i,j;
	for(i=0;i<row+4;i++)
	{
		for(j=0;j<col+4;j++)
		{
			if(i<2||i>=row+2||j<2||j>=col+2)
			{
				chess[i][j]=-1;
			}
			else
			{
				chess[i][j]=0;	
			}
		}
	}
	min=1;
	max=row*col;
	result=0;
}

//结果
void print()
{
	int i,j;
	for(i=2;i<row+2;i++)
	{
		for(j=2;j<col+2;j++)
		{
			printf("%3d ",chess[i][j]);	
		}	
		printf("\n");
	}	
} 

//获取一个位置的可走数量
int getNext(int m,int n)
{
	if(chess[m][n]!=0)
	{
		return 10;
	}
	int count=0;
	int i;
	int p,q;
	for(i=0;i<8;i++)
	{
		p=m+turn[i][0];
		q=n+turn[i][1];
		if(chess[p][q]==0)
		{
			count++;
		}
	}	
	return count;
} 

//深度搜索答案
void dfs(int m,int n,int num)
{
	if(num>=max)
	{
		print();
		result++;
		exit(0);
//		return;	
	}	
	chess[m][n]=num;
	
	Direct direct[8];
	int i,j;
	int p,q;
	for(i=0;i<8;i++)
	{
		p=m+turn[i][0];
		q=n+turn[i][1];
		direct[i].index=i;
		direct[i].count=getNext(p,q);
	}
	//将可走数量较少的排在前面
	for(i=0;i<7;i++)
	{
		for(j=i+1;j<8;j++)
		{
			if(direct[i].count>direct[j].count)
			{
				Direct t=direct[i];
				direct[i]=direct[j];
				direct[j]=t;	
			}	
		}	
	} 
	
	//继续深度搜索
	for(i=0;i<8;i++)
	{
		p=turn[direct[i].index][0]+m;
		q=turn[direct[i].index][1]+n;
		if(chess[p][q]==0)
		{
			dfs(p,q,num+1);
			chess[p][q]=0;
		}
	} 
} 

int main()
{
	input();
	init();
	dfs(x,y,min);
	printf("解的个数:%d\n",result);
	return 0;
}

设计思路

1.按人的搜索答案思想,馬每次到达一个位置后依次像八个方向的可走位置试探,直到踏满棋盘。
2.馬每次到达一个位置时,先计算下一个位置的八个方向中的可走位置个数,分别存入8个数组中,然后我们将该数组排好序。接着按照出路少到多的方向依次试探(贪心算法思想)。
3.贪心算法求解马踏棋盘问题效率极高,up主亲测90行90列的棋盘也是秒解。(贪心算法对于本问题成立的理论可以参考度娘,这里不再赘述)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值