问题描述
设计要求是马从棋盘上的一个位置出发,然后按照中国象棋的规则—马走日,来走下一步,直到马走完棋盘上的每一个位置终止。
#include <iostream>
#include <string.h>
#include <stdio.h>
using namespace std;
struct info {int x,y,out;};
const int dx[8]={-2,-2,-1,-1, 1, 1, 2, 2};
const int dy[8]={-1, 1,-2, 2,-2, 2,-1, 1};
const int R=6,C=6;
int board[10][10];
int outlet(int x,int y)
{
int ct=0;
for(int i=0;i<R;++i)
if(x+dx[i]<0||y+dy[i]<0||x+dx[i]>=R||y+dy[i]>=C||board[x+dx[i]][y+dy[i]]) continue;
else ++ct;
return ct;
}//计算(x,y)的出口数
void sort(info *p,int n)
{
for(int i=n-1;i>0;--i)
if(p[i].out<p[i-1].out) swap(p[i],p[i-1]);
else break;
}//按出口数由小到大排序
bool search(int x,int y,int step)
{
if(board[x][y]) return false;
if(step==R*C)
{
board[x][y]=step;
return true;
}
else
{
board[x][y]=step;
int i,j; info dir[8];
for(i=j=0;i<8;++i)
if(x+dx[i]<0||y+dy[i]<0||x+dx[i]>=R||y+dy[i]>=C||board[x+dx[i]][y+dy[i]]) continue;
else
{
dir[j].x=x+dx[i];dir[j].y=y+dy[i];
dir[j].out=outlet(dir[j].x,dir[j].y);
sort(dir,++j);
}
for(i=0;i<j;++i)
if(search(dir[i].x,dir[i].y,step+1)) return true;
board[x][y]=0;
return false;
}
}//求解
int main()
{
int i,j,m,n;
cin>>m>>n;
m=m-1;
n=n-1;
if(search(m,n,1))
{
for(i=0;i<R;i++)
{
for(j=0;j<C;++j)
{ memset(board,0,R*C*sizeof(int));
printf("%4d",board[i][j]);
}
cout<<endl;
}
}
else
printf("start at(%d,%d) has no solve!\n",i+1,j+1);
return 0;
}