主體思路
馬兒由用戶輸入,出現在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);
}