馬踏棋盤C語言實現
阿新 • • 發佈:2019-02-10
該程式碼為未優化演算法實現,8*8棋盤,挑選效率高的起始點(2,0),以及效率高的走法
每一次走法的嘗試都是回溯法,一條路走到黑,直到行不通,再重新開始
////////////////回溯法+遞迴//////////////圖的深度優先遍歷/////////////////////////////// #include <stdio.h> //#include <stdlib.h> #include <time.h> #define X 8 #define Y 8 int chess[X][Y]; /*int nextxy(int *x,int *y,int count) { switch(count) { case 0: if(*x+2<X && *y+1<Y && chess[*x+2][*y+1]==0) { *x+=2; *y+=1; return 1; } break; case 1: if(*x+2<X && *y-1>=0 && chess[*x+2][*y-1]==0) { *x+=2; *y-=1; return 1; } break; case 2: if(*x+1<X && *y-2>=0 && chess[*x+1][*y-2]==0) { *x+=1; *y-=2; return 1; } break; case 3: if(*x-1>=0 && *y-2>=0 && chess[*x-1][*y-2]==0) { *x-=1; *y-=2; return 1; } break; case 4: if(*x-2>=0 && *y-1>=0 && chess[*x-2][*y-1]==0) { *x-=2; *y-=1; return 1; } break; case 5: if(*x-2>=0 && *y+1<Y && chess[*x-2][*y+1]==0) { *x-=2; *y+=1; return 1; } break; case 6: if(*x-1>=0 && *y+2<Y && chess[*x-1][*y+2]==0) { *x-=1; *y+=2; return 1; } break; case 7: if(*x+1<X && *y+2<Y && chess[*x+1][*y+2]==0) { *x+=1; *y+=2; return 1; } break; default: break; } return 0; }*/ //與上面註釋掉的nextxy() 的走發不一樣,經測試這樣走效率更高 int nextxy(int *x,int *y,int count) { switch(count) { case 0: if(*x+2<X && *y-1>=0 && chess[*x+2][*y-1]==0) { *x+=2; *y-=1; return 1; } break; case 1: if(*x+2<X && *y+1<Y && chess[*x+2][*y+1]==0) { *x+=2; *y+=1; return 1; } break; case 2: if(*x+1<X && *y-2>=0 && chess[*x+1][*y-2]==0) { *x+=1; *y-=2; return 1; } break; case 3: if(*x+1<X && *y+2<Y && chess[*x+1][*y+2]==0) { *x+=1; *y+=2; return 1; } break; case 4: if(*x-2>=0 && *y-1>=0 && chess[*x-2][*y-1]==0) { *x-=2; *y-=1; return 1; } break; case 5: if(*x-2>=0 && *y+1<Y && chess[*x-2][*y+1]==0) { *x-=2; *y+=1; return 1; } break; case 6: if(*x-1>=0 && *y-2>=0 && chess[*x-1][*y-2]==0) { *x-=1; *y-=2; return 1; } break; case 7: if(*x-1>=0 && *y+2<Y && chess[*x-1][*y+2]==0) { *x-=1; *y+=2; return 1; } break; default: break; } return 0; } //輸出計算出來的走法,輸出的矩陣元素值表示走的第chess[i][j]步 void print() { int i,j; for(i=0;i<X;++i) { for(j=0;j<Y;++j) { printf("%2d\t",chess[i][j]); } printf("\n"); } printf("\n"); } //深度優先遍歷棋盤 //tag為標記變數每走一步,tag+1 int TravelChessBoard(int x,int y,int tag) { int x1=x,y1=y,flag=0; int <span style="font-family: Arial, Helvetica, sans-serif;">count=0; // 對現在的位置,每次從位置0出開始走</span> chess[x][y]=tag; if(tag==X*Y) { print();//列印棋盤 return 1; } //確定成功走出第一步 flag=nextxy(&x1,&y1,count); while(flag==0 && count<=7) { ++count; // 若行不通,則切換走的方向 flag=nextxy(&x1,&y1,count); } while(flag) { if(TravelChessBoard(x1,y1,tag+1)) // 成功走完全部 return 1; // 未成功走完,換個方向重新開始走 x1=x;y1=y; ++count; flag=nextxy(&x1,&y1,count); while(flag==0 && count<7) { ++count; flag=nextxy(&x1,&y1,count); } } if(flag==0) { chess[x][y]=0; } return 0; } int main() { int i,j; clock_t start,finish; start=clock(); for(i=0;i<X;++i) { for(j=0;j<Y;++j) chess[i][j]=0; } if(!TravelChessBoard(2,0,1)) //起始點(2,0) { printf("抱歉,馬踏棋盤失敗鳥~\n"); } finish=clock(); printf("\n本次計算一共耗時:%f秒\n\n",(double)(finish-start)/CLOCKS_PER_SEC); return 0; }