骑士周游

Homework:

在n*n棋盘上,按国际象棋的走马规则,从棋盘的任何一个方格开始,让马走遍所有的方格,每个方格至少并且只准走过一次。设计求解算法。

利用回溯法,试探性的走,不行折返,再试探...

 1  // 骑士周游(qishizhouyou),with method of trace back
 2  // Note:This program can list all probable ways , but costs a lot of time.
 3  // Compiled in Code::Blocks on Ubuntu platform
 4 
 5  // step[N*N]   record the direction of each step
 6  // move[8][2]  eight probable directions
 7  // chess[N][N] the order of points/grids
 8  // pro in function trace(int ,int ,int) means pro steps jumped
 9
11  #include  < iostream >
12  #include  < iomanip >
13  using   namespace  std;
14 
15 
16  const   int  N  =   8 ;
17  int  k  =   0 ,i  =   0 ;
18  int  step[N * N];
19  int  move[ 8 ][ 2 =  {{ 2 , 1 }, { 1 , 2 }, { - 1 , 2 }, { - 2 , 1 }, { - 2 , - 1 }, { - 1 , - 2 }, { 1 , - 2 }, { 2 , - 1 }};  // counter-clockwise direction
20  int  chess[N][N];
21 
22  void  Init()  // initialize
23  {
24       for ( int  i = 0 ;i < N * N; ++ i)
25      {
26          step[i]  =   - 1 ;
27          chess[i / 8 ][i % 8 =   0 ;
28      }
29  }
30 
31 
32  bool  canJump( int  x, int  y)
33  {
34       if (x >= 0   &&  x < &&  y >= 0   &&  y < &&  chess[x][y] == 0 )
35           return   true ;
36       else
37           return   false ;
38  }
39 
40  void  Print()
41  {
42       for ( int  i = 0 ;i < N; ++ i)
43      {
44           for ( int  j = 0 ;j < N; ++ j)
45              cout << setw( 3 ) << chess[i][j];
46          cout << endl;
47      }
48      cout << endl;
49  }
50 
51 
52  void  trace( int  pro, int  x, int  y)
53  {
54       if (pro >= N * N)
55      {
56          Print();
57      }
58       else
59      {
60           for ( int  i = 0 ;i < 8 ; ++ i)
61          {
62               if (canJump(x + move[i][ 0 ], y + move[i][ 1 ]))
63              {
64                  x += move[i][ 0 ];
65                  y += move[i][ 1 ];
66                  chess[x][y] = pro + 1 ;
67                  step[pro] = i;
68                  trace(pro + 1 ,x,y); // after finish this step,try next step
69 
70                  chess[x][y] = 0 ; // trace back
71                  x -= move[i][ 0 ];
72                  y -= move[i][ 1 ];
73              }
74          }
75      }
76  }
77 
78 
79 
80  int  main()
81  {
82       int  x = 0 ;
83       int  y = 0 ;
84      chess[x][y] = 1 ;
85      trace( 1 ,x,y);
86 
87       return   0 ;
88  }
89 

可试探出所有可能走法。时间复杂度,极大……O( 8n*n)

较优算法:
对于8*8棋盘
设定每个方格的权重(权重越低越不容易到达):

Code
//<< C++ How To Program >> Fifth Edition
{
    {
23444432},
    {
34666643},
    {
46888864},
    {
46888864},
    {
46888864},
    {
46888864},
    {
34666643},
    {
23444432}
}

每次取权重低的先走,依然是用回溯法。
对于N*N,每格权重算法:

Code
//[x][y] 方格的权重算法
int Weight(int x, int y)
{
    
int w = 0;
    
for(int i = 0; i < N; ++i)
    {
        
if( canJump(x + move[i][0] ,y+move[i][1]) )
            
++w;
    }
    
return w;
}

实现:再议了。
据说还有谈心算法什么的。有时间再看看,这题是做完了。

 

奇慢无比……

转载于:https://www.cnblogs.com/qzchenwl/archive/2008/10/02/1303165.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值