赞
踩
八皇后问题是一个古老而著名的问题,是回溯算法的典型例题。该问题是十九世纪著名的数学家高斯1850年提出:在8X8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线(对角线)上,问有多少种摆法。
回溯法详解请参考链接http://baike.baidu.com/view/6056523.htm
下面的C代码可以解决N皇后问题,8皇后问题的解是92。
- #include <stdio.h>
- #include <stdlib.h>
-
- #define max 8
-
- int queen[max], sum=0; /* max为棋盘最大坐标 */
-
- void show() /* 输出所有皇后的坐标 */
- {
- int i;
- for(i = 0; i < max; i++)
- {
- printf("(%d,%d) ", i, queen[i]);
- }
- printf("\n");
- sum++;
- }
-
- int check(int n) /* 检查当前列能否放置皇后 */
- {
- int i;
- for(i = 0; i < n; i++) /* 检查横排和对角线上是否可以放置皇后 */
- {
- if(queen[i] == queen[n] || abs(queen[i] - queen[n]) == (n - i))
- {
- return 1;
- }
- }
- return 0;
- }
-
- void put(int n) /* 回溯尝试皇后位置,n为横坐标 */
- {
- int i;
- for(i = 0; i < max; i++)
- {
- queen[n] = i; /* 将皇后摆到当前循环到的位置 */
- if(!check(n))
- {
- if(n == max - 1)
- {
- show(); /* 如果全部摆好,则输出所有皇后的坐标 */
- }
- else
- {
- put(n + 1); /* 否则继续摆放下一个皇后 */
- }
- }
- }
- }
-
- int main()
- {
- put(0); /* 从横坐标为0开始依次尝试 */
- printf("%d", sum);
- return 0;
- }
程序运行部分结果截图:
- int queenNumber=0;
- //判断是否是合法的序列
- bool JudgeValid(int* array,int length){
- for(int i=0;i<length-1;i++)
- for(int j=i+1;j<length;j++){
- if(i-j==array[i]-array[j] || j-i==array[i]-array[j])
- return false;
- }
- return true;
- }
-
- //获得皇后问题的全排列
- void QueuePermutation(int* array,int beginIndex,int length){
- if(beginIndex==length){
- if(JudgeValid(array,length))
- ++queenNumber;
- }else{
- for(int curSub=beginIndex;curSub!=length;curSub++){
- int temp=array[beginIndex];
- array[beginIndex]=array[curSub];
- array[curSub]=temp;
- QueuePermutation(array,beginIndex+1,length);
- temp=array[beginIndex];
- array[beginIndex]=array[curSub];
- array[curSub]=temp;
- }
- }
- }
-
- //可以解决N皇后问题
- void QueueProgram(int length){
- int *array=new int[length];
- for(int i=0;i<length;i++)
- array[i]=i;//初始化数组
- QueuePermutation(array,0,length);
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。