主体思路
马儿由用户输入,出现在8*8棋盘(棋盘可以改大小)的任意位置,接下来它会根据选择最难走的路,这一想法不断前进,每次前进都会判断该位置的下一步走哪里最困难能走的路最少,先走最少的路,之后才能走的顺利,否则容易卡很久。这算是数据结构的作业,能力有限,代码比较长,高手勿喷。。。
代码
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
//X,Y值可以修改,但是棋盘必须在6*6-9*9之间
#define X 8
#define Y 8
//全局变量
int list[X][Y];//X*Y棋盘
int HTry1[8]={-2,-1,1,2,2,1,-1,-2};
int HTry2[8]={1,2,2,1,-1,-2,-2,-1};
//**链表准备**
//创建链表
struct Node
{
int x;//列项
int y;//横项
int index;//当前步数
int lt[8];//当前可行路线
struct Node* next;//指针指向下一步的结点
};
//初始化链表
struct Node* createList()
{
struct Node* headNode = (struct Node*)malloc(sizeof(struct Node));
headNode->next = NULL;
return headNode;//返回头结点
}
//创建结点
struct Node* createNode(int x,int y,int index)
{
int i;
struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
newNode->x = x;
newNode->y = y;
newNode->index = index;
for(i=0;i<8;i++){
if(x+HTry1[i]>=0&&y+HTry2[i]>=0&&x+HTry1[i]<=X-1&&y+HTry2[i]<=Y-1&&list[x+HTry1[i]][y+HTry2[i]]==0)
{
newNode->lt[i]=(x+HTry1[i])*10+y+HTry2[i];
}
}
newNode->next = NULL;
return newNode;
}
//打印链表
void printList(struct Node* headNode)
{
struct Node* pMove = headNode->next;
int i;
while(pMove)
{
printf("(%d,%d,%d)->",pMove->x,pMove->y,pMove->index);
pMove = pMove->next;
}
}
//打印棋盘
void printarg(struct Node* headNode)
{
struct Node* pMove = headNode->next;
int i,j;
int arg[X][Y];
for(i=0;i<X;i++){
for(j=0;j<Y;j++){
arg[i][j]=0;
}
}
printf("\n");
while(pMove)
{
arg[pMove->x][pMove->y]=pMove->index;
pMove = pMove->next;
}
for(i=0;i<X;i++){
for(j=0;j<Y;j++){
printf("%-3d",arg[i][j]);
}
printf("\n");
}
}
//获取指向链表最后一个元素的指针p
struct Node* P(struct Node* L){
struct Node* p=L;
while(p->next!=NULL){
p=p->next;
}
return p;
}
//判断该位置有几个可行点
int num(int x,int y){
int a=0,i;
for(i=0;i<8;i++){
if(x+HTry1[i]>=0&&y+HTry2[i]>=0&&x+HTry1[i]<=X-1&&y+HTry2[i]<=Y-1&&list[x+HTry1[i]][y+HTry2[i]]==0)
{
a+=1;
}
}
return a;
}
//尾部插入结点
//马前进
//入栈函数
int insertNode(struct Node* headNode,int x,int y,int index)
{
if(x>=0 && y>=0 && x<=X-1 && y<=Y-1){
struct Node* p = headNode;
while(p->next!=NULL){
p=p->next;
}
struct Node* newNode = createNode(x,y,index);
newNode->next = p->next;
p->next = newNode;
return 1;
}
return 0;
}
//马回头
//出栈函数
int back(struct Node* headNode){
struct Node* p = headNode;
struct Node* q;
int a;
while(p->next->next!=NULL){
p=p->next;
}
q=p->next;
p->next=p->next->next;
a = (q->x)*10+(q->y);
free(q);
return a;
}
int main()
{
int a=0,b=0,h,i,n=1,j,index=1,index2,min;
int ls[8],ls1[8]={9,9,9,9,9,9,9,9};
struct Node* L = createList();//获得头节点,头节点没有数据域
struct Node* p = L;//指针p主要用于遍历结点
//获得用户输入
printf("在%d*%d的棋盘中,请输入马所在的初始位置(输入范围内的整数坐标,空格相隔):",X,Y);
while(1){
scanf("%d",&i);
scanf("%d",&j);
if(i>=0&&i<X&&j>=0&&j<=Y)break;
else printf("\n输入不合法!!!请重新输入:\n");
}
//初始化首元结点,另该位置为1,表示已经走过
insertNode(L,i,j,index);
list[i][j]=1;
//主循环,马儿会在此走完其余的棋盘
while(n<X*Y){
//初始化数据,或者重置数据
index2=0;
for(h=0;h<8;h++){
ls1[h]=9;
}
//测试可前进
p=P(L);
for(h=0;h<8;h++){
if(p->lt[h]>=0)
{
index2++;
}
}
//回溯
if(index2==0){
a = back(L);
n--;
list[a/10][a%10]=0;
p=P(L);
for(i=0;i<8;i++){
if(p->lt[i]==a){
p->lt[i]=-1;
}
}i=0;
}
//尝试插入结点
else{
//获得最难走的路
p=P(L);
for(h=0;h<8;h++){
if(p->lt[h]<0){
continue;
}
if (p->lt[h]>=0&&p->lt[h]<=9){
i=0;
j=p->lt[h];
}
else if(p->lt[h]>=10){
i=p->lt[h]/10;
j=p->lt[h]%10;
}
ls1[h]=num(i,j);
}
min=9;
//该位置最难走的路的可行数min
for(h=0;h<8;h++){
if(ls1[h]<min){
min=ls1[h];
}
}
//获得最难走的位置的坐标i,j
for(h=0;h<8;h++){
if(ls1[h]==min){
i=p->lt[h]/10;
j=p->lt[h]%10;
break;
}
}
//插入结点
insertNode(L,i,j,++n);
list[i][j]=1;
}
}
printarg(L);
}