C语言学习--八皇后问题

问题描述:

在8X8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。

程序设计:

1、一维数组a[17],数组分成三段,第一段a[0]用来标记八皇后安置完成;第二段a[1,8]用来标记列位置有无子,方便判断列冲突;第三段a[9,16]用来标记存储位置。

2、关键算法 递归判断位置,eightQueens 。

3、对角线位置互斥判断, isDiagonal。

4、输出函数, printResult。

算法描述:

1、首次传入为数组a和起始列变量i=1,判断标记为a[0]是否为1,为1进入2,否则进入3;

2、打印数组a[9,16];

3、测试j是否小于8,下于则递归结束,否则探测j列是否合法,合法进入4,否则j++,重走3;

4、列标记为a[j]置1,存储位置标记a[8+i]置为i,j组合的位置代号(i*10+j);

5、判断是否已安置所有皇后,是则将标记为a[0]置1。

6、列号加1,再次递归。

7、清除本次递归设置的值,为方便回溯、重新寻找其他组合的,返回3。

  1 /*
  2     功能: Eight queens
  3     时间: 2014-08-31 14:34:56
  4 */
  5 #include <stdio.h>
  6
  7 int c = 1; //简单的分页
  8
  9 void eightQueens(int *a, int i);    //递归求解
 10 int isDiagonal(int *a, int n);        //判断是否同对角线
 11 void printResult(int *a);            //输出结果
 12
 13 int main(void)
 14 {
 15     int a[17];
 16     int i;
 17
 18     //初始化棋盘
 19     for(i=0; i<17; i++)
 20     {
 21         a[i] = 0;
 22     }
 23
 24     //求解方法
 25     eightQueens(a, 1);
 26
 27     return 0;
 28 }
 29
 30 void eightQueens(int *a, int i)
 31 {
 32     int j;
 33
 34     if(a[0]==1)
 35     {
 36         //输出结果
 37         printResult(a);
 38     }
 39     else
 40     {
 41         for(j=1; j<9; j++)
 42         {
 43             if(a[j] != 1 && isDiagonal(a, i*10+j)) //非同行、非同列、不再对角线。
 44             {
 45                 a[j] = 1;
 46                 a[8+i] = i*10+j;
 47                 if(i == 8) a[0] = 1;
 48                 //递归
 49                 if(i<=8)
 50                 {
 51                     eightQueens(a, i+1);
 52                 }
 53                 a[j] = 0;
 54                 a[8+i] = 0;
 55                 a[0] = 0;
 56             }
 57         }
 58     }
 59
 60 }
 61
 62 //判断是否同对角线
 63 int isDiagonal(int *a, int n)
 64 {
 65     int aDcd, aBit;    //已标记的行列坐标
 66     int nDcd, nBit; //待判断的行列坐标
 67     int tDcd, tBit; //已标记与待判断行列差值
 68     int k;
 69
 70     nDcd = n/10;
 71     nBit = n%10;
 72
 73     for(k=9; k<17; k++)
 74     {
 75         if(a[k] != 0)
 76         {
 77             //分离已标记坐标的行与列
 78             aDcd = a[k]/10;
 79             aBit = a[k]%10;
 80
 81             tDcd = nDcd - aDcd; //计算行差值
 82             tBit = nBit - aBit; //计算列差值
 83
 84             if((tDcd-tBit) == 0 || (tDcd + tBit) == 0) //行列差值的绝对值相等则在同对角线
 85             {
 86                 return 0;
 87             }
 88         }
 89         else
 90         {
 91             return 1;
 92         }
 93     }
 94     return 1;
 95 }
 96
 97 //输出结果
 98 void printResult(int *a)
 99 {
100     int m;
101
102     printf("Scheme %d :\n", c);
103     for(m=9; m<17; m++)
104     {
105         printf("a[%d]\t", a[m]);
106     }
107     printf("\n");
108
109     c++;
110
111     if(c%10 == 0){
112         getchar();
113     }
114 }

C语言学习才开始,许多还不太熟悉,还没看到算法,只是凭自己想的写的,比较粗糙,至于优化之类留与后期吧。

时间: 2024-12-14 17:22:27

C语言学习--八皇后问题的相关文章

回溯算法-C#语言解决八皇后问题的写法与优化

结合问题说方案,首先先说问题: 八皇后问题:在8X8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行.同一列或同一斜线上,问有多少种摆法. 嗯,这个问题已经被使用各种语言解答一万遍了,大多还是回溯法解决的. 关于回溯算法:个人理解为就是优化的穷举算法,穷举算法是指列出所有的可能情况,而回溯算法则是试探发现问题"剪枝"回退到上个节点,换一条路,能够大大提高求解效率. 具体到8皇后问题上来说,需要考虑以下几点: 1)将8个皇后定义为8行中的相对位置来标识,考虑增

使用java语言实现八皇后问题

八皇后问题,在一个8X8的棋盘中,放置八个棋子,每个棋子的上下左右,左上左下,右上右下方向上不得有其他棋子.正确答案为92中,接下来用java语言实现. 解: package eightQuen; /** * 八皇后问题 * * @author 83771 * */ public class eight { // 定义一个数组 表示棋盘 public static Integer[][] checkerBoard = new Integer[8][8]; // 棋盘副本 public stati

C语言解决八皇后问题

1 #include <stdio.h> 2 #include <stdlib.h> 3 4 /* this code is used to cope with the problem of the eight queens. 5 * array borad[9][9] is a virtual borad. 6 * line 0 and volumn 0 is ignored. 7 * at first we find a place to set a queen on it,

python学习八皇后问题

1 import random 2 #冲突检查,在定义state时,采用state来标志每个皇后的位置,其中索引用来表示横坐标,基对应的值表示纵坐标,例如: state[0]=3,表示该皇后位于第1行的第4列上 3 def conflict(state, nextX): 4 nextY = len(state) 5 for i in range(nextY): 6 #如果下一个皇后的位置与当前的皇后位置相邻(包括上下,左右)或在同一对角线上,则说明有冲突,需要重新摆放 7 if abs(stat

八皇后,回溯与递归(Python实现)

八皇后,回溯与递归(Python实现) 八皇后问题是十九世纪著名的数学家高斯1850年提出 .以下为python语言的八皇后代码,摘自<Python基础教程>,代码相对于其他语言,来得短小且一次性可以打印出92种结果.同时可以扩展为九皇后,十皇后问题. 问题:在一个8*8棋盘上,每一行放置一个皇后旗子,且它们不冲突.冲突定义:同一列不能有两个皇后,每一个对角线也不能有两个皇后.当然,三个皇后也是不行的,四个也是不行的,凭你的智商应该可以理解吧. 解决方案:回溯与递归. 介绍: 1.回溯法 回溯

Python学习二(生成器和八皇后算法)

看书看到迭代器和生成器了,一般的使用是没什么问题的,不过很多时候并不能用的很习惯 书中例举了经典的八皇后问题,作为一个程序员怎么能够放过做题的机会呢,于是乎先自己来一遍,于是有了下面这个ugly的代码 def table(m, lst): '''绘制m列的棋盘,每行有个皇后旗子''' head = '┌' + '─┬' * (m-1) + '─┐' row = lambda x: '│' + ' │' * x + '╳│' + ' │' * (m - x - 1) trow = '├' + '─

C++语言学习(八)——操作符重载

C++语言学习(八)--操作符重载 一.操作符重载基础 1.操作符重载的语法 通过operator关键字可以定义特殊的函数,operator本质是通过函数重载操作符. Type operator operatorname(const Type p1, const Type p2) { Type ret; return ret; } 2.友元函数重载操作符 可以将操作符重载函数声明为友元函数. #include <iostream> using namespace std; class Comp

C++语言学习(十八)——异常处理

C++语言学习(十八)--异常处理 一.C语言异常处理 异常是指程序在运行过程中产生可预料的执行分支.如除0操作,数组访问越界.要打开的文件不存在.Bug是指程序中的错误,是不被预期的运行方式.如野指针.堆空间使用结束未释放.C语言中处理异常的方式一般是使用if....else...分支语句. double divide(double a, double b) { const double delta = 0.000000000000001; double ret = 0; if( !((-de

八皇后问题(C语言版本)

八皇后问题是一个古老而著名的问题,是回溯算法的典型例题.该问题是十九世纪著名的数学家高斯1850年提出:在8X8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行.同一列或同一斜线上,问有多少种摆法. 回溯法详解请参考链接http://baike.baidu.com/view/6056523.htm 下面的C代码可以解决N皇后问题,8皇后问题的解是92. #include <stdio.h> #include <stdlib.h> #define max