八皇后问题

周末闲来无事,忽然想起大学时候学《数据结构》时候的期末上机考试,要求在两个小时内完成两道编程的题目。其中一道题目就是让编程解决“八皇后问题”。现在想起来还是挺有意思,就打算用 C# 再实现一次 :)

八皇后问题的大致意思是这样的:在一个 8*8 的矩形格子中排放 8 个皇后,要满足的条件包括:任意两个皇后都不能在同一行、同一列,也不能在同一条对角线(斜率等于1或-1)。

在考试的时候,我是用递归的方法解决的。现在想一想,还是用递归比较方便。但是需要注意的是,递归有个很大的毛病,就是递归的规模不太好控制,而且在递归很深的程序中,要调试也是一个很伤脑筋的问题。在有的公司,递归就是基本上禁止的。不过这里我就不去考虑非递归的解决方案了,反正是娱乐娱乐,何必自找麻烦呢:)

在使用递归解决此问题的时候,我采用的方法大致是这样:

  • 将一个皇后向下移动一个位置;
  • 如果没有成功移动(比如已经超出边界),失败;
  • 如果成功移动,则判断当前位置是否可用(和其他的皇后时候冲突)?如果冲突,则重做 1;
  • 继续给下一个皇后安排位置。
结束条件就是如果第一个皇后的所有位置都尝试完毕仍然没有可用的解决方案或者最后一个皇后已经安排完毕。

代码如下:

 1 None.gif //  AppEntry.cs
 2 None.gif using  System;
 3 None.gif
 4 None.gif namespace  Chenglin
 5 ExpandedBlockStart.gifContractedBlock.gif dot.gif {
 6InBlock.gif  class AppEntry
 7ExpandedSubBlockStart.gifContractedSubBlock.gif  dot.gif{
 8InBlock.gif    static void Main(string[] args)
 9ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
10InBlock.gif      int queenNumber = 8;    
11InBlock.gif      QueenRowCollection q = new QueenRowCollection(queenNumber);
12InBlock.gif      
13InBlock.gif      bool flag;
14InBlock.gif      DateTime timeStarted = DateTime.Now;
15InBlock.gif      flag = q.PositionQueens();
16InBlock.gif      TimeSpan ts = DateTime.Now.Subtract( timeStarted );
17InBlock.gif      
18InBlock.gif      
19ExpandedSubBlockStart.gifContractedSubBlock.gif      if( flag ) dot.gif{
20InBlock.gif        Console.WriteLine( q.ToString() );
21ExpandedSubBlockEnd.gif      }

22ExpandedSubBlockStart.gifContractedSubBlock.gif      else dot.gif{
23InBlock.gif        Console.WriteLine( "Faileddot.gif" );
24ExpandedSubBlockEnd.gif      }

25InBlock.gif      
26InBlock.gif      Console.WriteLine( "{0} seconds has been elapsed.", ts.TotalSeconds );
27ExpandedSubBlockEnd.gif    }

28ExpandedSubBlockEnd.gif  }

29ExpandedBlockEnd.gif}
 1 None.gif //  QueenRowCollection.cs
 2 None.gif using  System;
 3 None.gif using  System.Text;
 4 None.gif
 5 None.gif namespace  Chenglin
 6 ExpandedBlockStart.gifContractedBlock.gif dot.gif {
 7InBlock.gif  public class QueenRowCollection
 8ExpandedSubBlockStart.gifContractedSubBlock.gif  dot.gif{
 9InBlock.gif
10ExpandedSubBlockStart.gifContractedSubBlock.gif    public QueenRowCollection( int numberOfQueens )dot.gif{
11InBlock.gif      this.numberOfQueens = numberOfQueens;
12InBlock.gif      this.rows = new QueenRow[ numberOfQueens ];
13InBlock.gif
14ExpandedSubBlockStart.gifContractedSubBlock.gif      forint i=0;i<numberOfQueens;i++ )dot.gif{
15InBlock.gif        rows[i] = new QueenRow( numberOfQueens );
16ExpandedSubBlockEnd.gif      }

17ExpandedSubBlockEnd.gif    }

18InBlock.gif
19InBlock.gif    public bool PositionQueens()
20ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
21InBlock.gif      return PositionQueen( 0 );
22ExpandedSubBlockEnd.gif    }

23InBlock.gif
24InBlock.gif    private bool PositionQueen( int row )
25ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
26ExpandedSubBlockStart.gifContractedSubBlock.gif      if( row>=this.numberOfQueens ) dot.gif{
27InBlock.gif        return true;
28ExpandedSubBlockEnd.gif      }

29InBlock.gif
30InBlock.gif      QueenRow q = rows[row];
31InBlock.gif      while( q.MoveNext() )
32ExpandedSubBlockStart.gifContractedSubBlock.gif      dot.gif{
33ExpandedSubBlockStart.gifContractedSubBlock.gif        if( PositionAvailable( row, q.CurrentPosition ) ) dot.gif{
34InBlock.gif          // An available position has been found for the current queen,
35InBlock.gif          // and try to find a proper position for the next queen.
36InBlock.gif          //
37InBlock.gif          // If no available position can be found for the next queen,
38InBlock.gif          // the current queen should move to the next position and try again.
39InBlock.gif          //
40InBlock.gif          if( PositionQueen( row+1 ) )
41ExpandedSubBlockStart.gifContractedSubBlock.gif          dot.gif{
42InBlock.gif            // Both the current queen and the next queen
43InBlock.gif            // have found available positions.
44InBlock.gif            //
45InBlock.gif            return true;
46ExpandedSubBlockEnd.gif          }

47ExpandedSubBlockEnd.gif        }

48ExpandedSubBlockEnd.gif      }

49InBlock.gif
50InBlock.gif      // No position is available for the current queen,
51InBlock.gif      //
52InBlock.gif      return false;
53ExpandedSubBlockEnd.gif    }

54InBlock.gif
55ExpandedSubBlockStart.gifContractedSubBlock.gif    private bool PositionAvailable( int row, int column )dot.gif{
56InBlock.gif      forint i=row-1; i>=0; i-- )
57ExpandedSubBlockStart.gifContractedSubBlock.gif      dot.gif{
58InBlock.gif        if( rows[i].PositionOccupied( column ) )
59InBlock.gif          return false;
60InBlock.gif
61InBlock.gif        if( rows[i].PositionOccupied( column-(i-row) ) )
62InBlock.gif          return false;
63InBlock.gif
64InBlock.gif        if( rows[i].PositionOccupied( column+(i-row) ) )
65InBlock.gif          return false;
66ExpandedSubBlockEnd.gif      }

67InBlock.gif
68InBlock.gif      return true;
69ExpandedSubBlockEnd.gif    }

70InBlock.gif
71InBlock.gif    public override string ToString()
72ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
73InBlock.gif      StringBuilder s = new StringBuilder();
74InBlock.gif
75ExpandedSubBlockStart.gifContractedSubBlock.gif      foreach( QueenRow q in rows )dot.gif{
76InBlock.gif        s.AppendFormat( "{0}{1}", q, Environment.NewLine );
77ExpandedSubBlockEnd.gif      }

78InBlock.gif
79InBlock.gif      return s.ToString();
80ExpandedSubBlockEnd.gif    }

81InBlock.gif
82InBlock.gif    private int numberOfQueens;
83InBlock.gif    private QueenRow [] rows;
84ExpandedSubBlockEnd.gif  }

85ExpandedBlockEnd.gif}
 1 None.gif //  QueenRow.cs
 2 None.gif using  System;
 3 None.gif using  System.Text;
 4 None.gif
 5 None.gif namespace  Chenglin
 6 ExpandedBlockStart.gifContractedBlock.gif dot.gif {
 7InBlock.gif  public class QueenRow
 8ExpandedSubBlockStart.gifContractedSubBlock.gif  dot.gif{
 9InBlock.gif    public QueenRow( int numberOfPositions )
10ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
11InBlock.gif      this.numberOfPositions = numberOfPositions;
12InBlock.gif      this.currentPosition = -1;
13InBlock.gif      this.columns = new bool[ numberOfPositions ];
14ExpandedSubBlockEnd.gif    }

15InBlock.gif    
16ExpandedSubBlockStart.gifContractedSubBlock.gif    public bool MoveNext()dot.gif{
17ExpandedSubBlockStart.gifContractedSubBlock.gif      if( currentPosition>=0 && currentPosition<this.numberOfPositions )dot.gif{
18InBlock.gif        columns[currentPosition] = false;
19ExpandedSubBlockEnd.gif      }

20InBlock.gif      
21ExpandedSubBlockStart.gifContractedSubBlock.gif      if( currentPosition<this.numberOfPositions-1)dot.gif{
22InBlock.gif        currentPosition ++;
23InBlock.gif        columns[currentPosition] = true;
24InBlock.gif        return true;
25ExpandedSubBlockEnd.gif      }

26ExpandedSubBlockStart.gifContractedSubBlock.gif      else dot.gif{
27InBlock.gif        currentPosition = -1;
28InBlock.gif        return false;
29ExpandedSubBlockEnd.gif      }

30ExpandedSubBlockEnd.gif    }

31InBlock.gif    
32ExpandedSubBlockStart.gifContractedSubBlock.gif    public bool PositionOccupied( int column )dot.gif{
33ExpandedSubBlockStart.gifContractedSubBlock.gif      if( column<0 || column>=numberOfPositions )dot.gif{
34InBlock.gif        return false;
35ExpandedSubBlockEnd.gif      }

36InBlock.gif      
37InBlock.gif      return columns[column];
38ExpandedSubBlockEnd.gif    }

39InBlock.gif    
40InBlock.gif    public override string ToString()
41ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
42InBlock.gif      StringBuilder s = new StringBuilder();
43InBlock.gif      
44ExpandedSubBlockStart.gifContractedSubBlock.gif      foreachbool b in columns )dot.gif{
45InBlock.gif        s.AppendFormat( "{0} ", (b ? "*" : "-") );
46ExpandedSubBlockEnd.gif      }

47InBlock.gif      
48InBlock.gif      return s.ToString();
49ExpandedSubBlockEnd.gif    }

50InBlock.gif    
51InBlock.gif    public int CurrentPosition
52ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
53ExpandedSubBlockStart.gifContractedSubBlock.gif      get dot.gifreturn currentPosition; }
54ExpandedSubBlockEnd.gif    }

55InBlock.gif    
56InBlock.gif    private int currentPosition;
57InBlock.gif    private int numberOfPositions;
58InBlock.gif    private bool [] columns;
59ExpandedSubBlockEnd.gif  }

60ExpandedBlockEnd.gif}


程序运行的时候,当皇后个数增加的时候,运行的时间也会急剧增加!下面这副图表示了皇后个数与运行时间的大致关系: executetime.gif

转载于:https://www.cnblogs.com/chenglin/archive/2005/06/19/177225.html

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值