请帮帮忙,看看这个程序,怎样使马(国际象棋中的)遍历每一个格子(8*8),然后又回到起点.谢谢!
#include <stdio.h>
#include <time.h>
#include<iostream.h>#define MAX_SIZE 10
#define MAX_STEP MAX_SIZE * MAX_SIZE
typedef struct
{
long x;
long y;
} STEP;
static long TryX[]={ -2, -1, 1, 2, 2, 1, -1, -2 };
static long TryY[]={ 1, 2, 2, 1, -1, -2, -2, -1 };
static char Board[MAX_SIZE + 4][MAX_SIZE + 4]; //棋盘,比实际棋盘大4,因为有2格是边界。//边界为值为-1,空白值为0,有棋子为1。
static char ResultBoard[MAX_SIZE][MAX_SIZE]; //用于输出结果的棋盘。
static STEP Step[MAX_STEP]; //存储每一步的坐标。
static long CurStep; //当前步,第一步是0。
static long Results; //解的个数。
static long Hamilton; //能够回到起点的解的个数。
static long SIZES, STEPS; //实际的棋盘大小和步数。
void Init(void) //棋盘初始化。
{
for(long i=0; i < SIZES + 4; i++)
{
for(long j=0; j < SIZES + 4; j++)
{
Board[i][j]=0;
}
}for(long i1=0; i1 < SIZES + 4; i1++)
{
Board[i1][0]= -1;
Board[i1][SIZES + 3]= -1;
Board[0][i1]= -1;
Board[SIZES + 3][i1]= -1;
Board[i1][1]= -1;
Board[i1][SIZES + 2]= -1;
Board[1][i1]= -1;
Board[SIZES + 2][i1]= -1;
}Results=0;
Hamilton=0;
}
void Disp(void) //打印棋盘状态
{
cout<<" ******************* "<<endl;
for(long i=0; i < SIZES + 4; i++)for(long j=0; j < SIZES + 4; j++) cout<< Board[i][j]<<" ";
cout<<endl;}
void Result(void) //输出结果
{
long dx, dy;
dx=Step[CurStep].x - Step[0].x; //判断最后是否回到起点。
dy=Step[CurStep].y - Step[0].y;
Results++;cout<<"---------- Results ----------"<<Results;
cout<<endl;
if(dx * dx + dy * dy == 5)
{
Hamilton++;cout<<"---------- Hamilton ----------"<<Hamilton;
cout<<endl;
}
for(long i1=0; i1 < STEPS; i1++) ResultBoard[Step[i1].x - 2][Step[i1].y - 2]=i1 + 1;
for(long i=0; i < SIZES; i++)for(long j=0; j < SIZES; j++) cout<<ResultBoard[i][j]<<" ";
cout<<endl;
}
void PutIt(void)
{
long NextX, NextY;
for(long i=0; i < 8; i++) //8个方向上尝试,
{
NextX=Step[CurStep].x + TryX[i];
NextY=Step[CurStep].y + TryY[i];
if(Board[NextX][NextY] == 0) //如果这个位置是空,
{
Board[NextX][NextY]=1; //放置一个马,
++CurStep;
Step[CurStep].x=NextX;
Step[CurStep].y=NextY; //计入步数,
if(CurStep == STEPS - 1) //如果步数达到最大步数(棋盘全满),
{
Result(); //输出结果。
}PutIt(); //再做下一次尝试。
}
}Board[Step[CurStep].x][Step[CurStep].y]=0; //如果8个方向都不为空,将这次的马拿走,
--CurStep; //并且步数倒退1步。
}/* */
int main(void)
{
long SX, SY;
cout<<"Board size ?"<<endl;
cin>>SIZES;
STEPS=SIZES * SIZES;cout<<"Start at X?"<<endl;
cin>>SX;
cout<<"Start atY ?"<<endl;
cin>> SY;Init();
Disp();
/*CurStep=0;
Step[CurStep].x=SX + 1; //第一步由输入产生。
Step[CurStep].y=SY + 1;
Board[Step[CurStep].x][Step[CurStep].y]=1; //棋盘相应位置放置一个马
PutIt(); //开始遍历。Disp();
return 0;*/
#include <stdio.h>
#include <time.h>
#include<iostream.h>#define MAX_SIZE 10
#define MAX_STEP MAX_SIZE * MAX_SIZE
typedef struct
{
long x;
long y;
} STEP;
static long TryX[]={ -2, -1, 1, 2, 2, 1, -1, -2 };
static long TryY[]={ 1, 2, 2, 1, -1, -2, -2, -1 };
static char Board[MAX_SIZE + 4][MAX_SIZE + 4]; //棋盘,比实际棋盘大4,因为有2格是边界。//边界为值为-1,空白值为0,有棋子为1。
static char ResultBoard[MAX_SIZE][MAX_SIZE]; //用于输出结果的棋盘。
static STEP Step[MAX_STEP]; //存储每一步的坐标。
static long CurStep; //当前步,第一步是0。
static long Results; //解的个数。
static long Hamilton; //能够回到起点的解的个数。
static long SIZES, STEPS; //实际的棋盘大小和步数。
void Init(void) //棋盘初始化。
{
for(long i=0; i < SIZES + 4; i++)
{
for(long j=0; j < SIZES + 4; j++)
{
Board[i][j]=0;
}
}for(long i1=0; i1 < SIZES + 4; i1++)
{
Board[i1][0]= -1;
Board[i1][SIZES + 3]= -1;
Board[0][i1]= -1;
Board[SIZES + 3][i1]= -1;
Board[i1][1]= -1;
Board[i1][SIZES + 2]= -1;
Board[1][i1]= -1;
Board[SIZES + 2][i1]= -1;
}Results=0;
Hamilton=0;
}
void Disp(void) //打印棋盘状态
{
cout<<" ******************* "<<endl;
for(long i=0; i < SIZES + 4; i++)for(long j=0; j < SIZES + 4; j++) cout<< Board[i][j]<<" ";
cout<<endl;}
void Result(void) //输出结果
{
long dx, dy;
dx=Step[CurStep].x - Step[0].x; //判断最后是否回到起点。
dy=Step[CurStep].y - Step[0].y;
Results++;cout<<"---------- Results ----------"<<Results;
cout<<endl;
if(dx * dx + dy * dy == 5)
{
Hamilton++;cout<<"---------- Hamilton ----------"<<Hamilton;
cout<<endl;
}
for(long i1=0; i1 < STEPS; i1++) ResultBoard[Step[i1].x - 2][Step[i1].y - 2]=i1 + 1;
for(long i=0; i < SIZES; i++)for(long j=0; j < SIZES; j++) cout<<ResultBoard[i][j]<<" ";
cout<<endl;
}
void PutIt(void)
{
long NextX, NextY;
for(long i=0; i < 8; i++) //8个方向上尝试,
{
NextX=Step[CurStep].x + TryX[i];
NextY=Step[CurStep].y + TryY[i];
if(Board[NextX][NextY] == 0) //如果这个位置是空,
{
Board[NextX][NextY]=1; //放置一个马,
++CurStep;
Step[CurStep].x=NextX;
Step[CurStep].y=NextY; //计入步数,
if(CurStep == STEPS - 1) //如果步数达到最大步数(棋盘全满),
{
Result(); //输出结果。
}PutIt(); //再做下一次尝试。
}
}Board[Step[CurStep].x][Step[CurStep].y]=0; //如果8个方向都不为空,将这次的马拿走,
--CurStep; //并且步数倒退1步。
}/* */
int main(void)
{
long SX, SY;
cout<<"Board size ?"<<endl;
cin>>SIZES;
STEPS=SIZES * SIZES;cout<<"Start at X?"<<endl;
cin>>SX;
cout<<"Start atY ?"<<endl;
cin>> SY;Init();
Disp();
/*CurStep=0;
Step[CurStep].x=SX + 1; //第一步由输入产生。
Step[CurStep].y=SY + 1;
Board[Step[CurStep].x][Step[CurStep].y]=1; //棋盘相应位置放置一个马
PutIt(); //开始遍历。Disp();
return 0;*/
不过其实你可以遍历,算出可以回到起点的几个特殊位置(也许存在)# include < iostream.h >
# include < iomanip.h >
# include < stdlib.h >
# include < fstream.h >bool mai ( int , int );void main( )
{
int a = 0;
while ( a != 8 ) {
int b = 0;
while ( b != 8 )
if ( mai ( a , b ) )
b++;
a++;
}
cout << "从第1格到第64格全部走完了!!!" << endl;
}/////////////////////////////////////////////////////////////////bool mai( int row , int column )
{
int Zao ( int [ ] );
void print ( int [ ] [ 8 ] , int , int , int , int , double );
// srand ( time ( NULL ) );
// int row = rand ( ) % 7;
// int column = rand ( ) % 7;
int x = 1;
static xx = 0;
int board [ 8 ] [ 8 ] = { 0 } ; // 棋盘
int CurrentRow = row; // 骑士初始位置,行
int CurrentColumn = column; // 骑士初始位置,列
board [ CurrentRow ] [ CurrentColumn ] = 1; // 走过的标记
int horizontal [ 8 ]; // 列
int vertical [ 8 ]; // 行
horizontal [ 0 ] = 2; // 8种移动方式之列
horizontal [ 1 ] = 1;
horizontal [ 2 ] = -1;
horizontal [ 3 ] = -2;
horizontal [ 4 ] = -2;
horizontal [ 5 ] = -1;
horizontal [ 6 ] = 1;
horizontal [ 7 ] = 2;
vertical [ 0 ] = -1; // 8种移动方式之行
vertical [ 1 ] = -2;
vertical [ 2 ] = -2;
vertical [ 3 ] = -1;
vertical [ 4 ] = 1;
vertical [ 5 ] = 2;
vertical [ 6 ] = 2;
vertical [ 7 ] = 1;
int accessibility [ 8 ] [ 8 ] = { { 2,3,4,4,4,4,3,2 },
{ 3,4,6,6,6,6,4,3 } ,
{ 4,6,8,8,8,8,6,4 } ,
{ 4,6,8,8,8,8,6,4 } ,
{ 4,6,8,8,8,8,6,4 } ,
{ 4,6,8,8,8,8,6,4 } ,
{ 3,4,6,6,6,6,4,3 } ,
{ 2,3,4,4,4,4,3,2 } }; // 棋盘相应点的难易值
int a = 1;
while ( x ) {
int nan [ 8 ] = { -1 , -1 , -1 , -1 , -1 , -1 , -1 , -1 }; // 保存难易值
for ( int moveNumber = 0; moveNumber < 8; moveNumber++ )
if ( CurrentRow + vertical [ moveNumber ] >= 0 && // 检查行,列,是否走过
CurrentRow + vertical [ moveNumber ] < 8 &&
CurrentColumn + horizontal [ moveNumber ] >= 0 &&
CurrentColumn + horizontal [ moveNumber ] < 8 &&
board [ CurrentRow + vertical [ moveNumber ] ]
[ CurrentColumn + horizontal [ moveNumber ] ] == 0 )
nan [ moveNumber ] = accessibility [ CurrentRow + vertical [ moveNumber ] ]
[ CurrentColumn + horizontal [ moveNumber ] ];// 难易值
int moveNumber1; // 最难走的移动方式
moveNumber1 = Zao ( nan );
// print ( board , a , row , column );
if ( moveNumber1 == 9 ) {
if ( a == 64 ) {
// cout << "走完了全部的格子!!!" << endl;
x = 0;
print ( board , a , row , column , xx);
// cin.get ( );
xx++;
return true;
}
else {
// cout << "走不动了!一共走了" << a << "步" << endl;
x = 0;
xx++;
return false;
}
}
else
{
a++;
CurrentRow += vertical [ moveNumber1 ]; // 相应移动方式移动后行的变化
CurrentColumn += horizontal [ moveNumber1 ]; // 相应移动方式移动后列的变化
board [ CurrentRow ] [ CurrentColumn ] = a; // 走过的标记
}
}
}/////////////////////找出最难走的//////////////////////int Zao( int nan [ ] )
{
int temp = 9;
for ( int i = 0; i < 8; i++ )
if ( temp > nan [ i ] && nan [ i ] != -1 )
temp = nan [ i ];
if ( temp != 9 ) {
int temp2 [ 8 ] = { 0 }; // 纪录满足条件的元素的下标
int t = 0; // 满足条件下标++
for ( int j = 0; j < 8; j++ )
if ( temp == nan [ j ] ) {
temp2 [ t ] = j + 1;
t++;
} // temp2中按顺序保存了nan中满足条件的元素的下标
int temp3 = 0; // 纪录满足条件的元素个数
for ( int jj = 0; jj < 8; jj++ )
if ( temp2 [ jj ] != 0 )
temp3++;
int temp4 = rand ( ) % temp3; // 随机选取满座条件的下标
temp = temp2 [ temp4 ] - 1;
}
return temp;
}////////////////////输出走过的格子//////////////void print( int b [ ] [ 8 ] , int a , int r , int c , int xx)
{ ofstream outfile ("ltt.txt",ios::app); // 输出到文件
outfile << "初始位置是: 行 " << r + 1 << " 列 " << c + 1 << " 一共走了" << xx << "回" << endl;
for ( int x = 0; x < 8; x++ )
outfile << " " << x + 1 << "列";
outfile << endl;
for ( int i = 0; i < 8; i++ ) {
outfile << i + 1 << "行";
for ( int j = 0; j < 8; j++ ) {
outfile << setw ( 4 ) << b [ i ] [ j ] << " ";
}
outfile << endl;
}
outfile << endl;
}