鱼C论坛

 找回密码
 立即注册
查看: 7496|回复: 31

[技术交流] 八皇后问题与回溯法

[复制链接]
发表于 2015-3-27 17:27:21 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 spy 于 2015-12-20 00:34 编辑
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <time.h>
  4. #include <conio.h>

  5. /* 此程序在vc6.0下编译运行是正确的,
  6.     在vs2008上编译成功,但运行会出现stack overflow !
  7.     高版本的编译器默认分配的的栈空间小一些,
  8.     应该可以在编译器里设置默认分配的栈的大小的,
  9.     如果不能设置的话可以将皇后个数减少。
  10. */

  11. //NUM大于8时, 频繁的递归调用会造成栈空间溢出
  12. #define NUM 8  //8个皇后

  13. void SolveQueen(char (*)[NUM], int, int);
  14. int NotSafety(char (*)[NUM], int, int);
  15. void MoveBack(char (*)[NUM], int, int);
  16. void ShowQueen(char (*)[NUM]);

  17. int cnt = 0;
  18. clock_t start, finish;

  19. void main()
  20. {
  21.         char chess[NUM][NUM];
  22.         int i, j;
  23.         for(i=0; i<NUM; i++)  //初始化棋盘
  24.         {
  25.                 for(j=0; j<NUM; j++)
  26.                 {
  27.                         chess[j] = '0';
  28.                 }
  29.         }
  30.         start = clock();
  31.         SolveQueen(chess, 0, 0);   //从(0,0)开始搜索
  32. }

  33. //NUM个皇后依次放置放到第0列到第NUM-1列的相应位置, 第j列上的皇后具体位置的确定需依次遍历第0行到第NUM-1行, 若第i行安全, 皇后位置chess(i,j)=1
  34. void SolveQueen(char (*chess)[NUM], int i, int j)
  35. {
  36.         while(i<NUM)
  37.         {
  38.                 if( !NotSafety(chess, i, j) )  //当前位置安全
  39.                 {
  40.                         *(*(chess+i)+j) = '1';  //置棋盘元素chess(i,j)=1
  41.                         if(j==NUM-1)  //找到一种方案
  42.                         {
  43.                                 ShowQueen(chess);  //将位置打印出来
  44.                                 chess[j] = '0'; //清0, 准备搜索下一行
  45.                         }
  46.                         else
  47.                         {
  48.                                 SolveQueen(chess, 0, j+1);  //搜索下一列
  49.                         }
  50.                 }
  51.                 i++;  //当前行不安全, 向下移动一行
  52.         }
  53.         if(i==NUM)  //当前列都不安全
  54.         {
  55.                 MoveBack(chess, 0, j-1);  //向前回溯一列
  56.         }
  57. }

  58. //判断当前位置是否安全, 若不安全返回1, 否则返回0
  59. int NotSafety(char (*chess)[NUM], int i, int j)
  60. {
  61.         //判断同一行是否安全
  62.         int m, n;
  63.         m = j-1;
  64.         if(m>=0) //←
  65.         {
  66.                 while( m>=0 && chess[m--]!='1' );
  67.                 if(chess[++m]=='1')
  68.                 {
  69.                         return 1;
  70.                 }
  71.         }

  72.         //判断主对角线是否安全
  73.         //左上方
  74.         m = i-1;  //↑
  75.         n = j-1;  //←
  76.         if(m>=0 && n>=0)
  77.         {
  78.                 while(m>=0 && n>=0 && chess[m--][n--]!='1');
  79.                 if(chess[++m][++n]=='1')
  80.                 {
  81.                         return 1;
  82.                 }
  83.         }

  84.         //判断次对角线是否安全
  85.         //左下方
  86.         m = i+1;  //↓
  87.         n = j-1;  //←
  88.         if(m<NUM && n>=0)
  89.         {
  90.                 while(m<NUM && n>=0 && chess[m++][n--]!='1');
  91.                 if(chess[--m][++n]=='1')
  92.                 {
  93.                         return 1;
  94.                 }
  95.         }
  96.         return 0;
  97. }

  98. //回溯至前一列, 继续对该列未搜索的行进行搜索
  99. void MoveBack(char (*chess)[NUM], int i, int j)
  100. {
  101.         while(chess[i++][j]!='1');  //找到之前搜索的行
  102.         chess[--i][j] = '0';  //该行无效
  103.         if(i==NUM-1 && j-1>=0)  //若该列的所有行都无效, 则继续回溯前一列; j-1>=0 表示当前列j=0 时就不能再向前回溯了, 因为回溯至0-1=-1列无意义
  104.         {
  105.                 MoveBack(chess, 0, j-1);
  106.         }
  107.         if(i==NUM-1 && j-1<0)  //若回溯到chess(NUM-1,0)则所有解法已全部遍历结束, 终止程序运行
  108.         {
  109.                 finish = clock();
  110.                 printf("\n%d皇后问题的解共有%d个!\n",NUM, cnt);
  111.                 printf("\n耗时%ldms\n", finish-start);
  112.                 _getch();
  113.                 exit(0);
  114.         }
  115.         SolveQueen(chess, i+1, j);  //搜索下一行
  116. }

  117. void ShowQueen(char (*chess)[NUM])
  118. {
  119.         int i, j;
  120.         printf("\n第%d种方案 :  ", ++cnt);
  121.         putchar('\n');
  122.         for(i=0; i<NUM; i++)
  123.         {
  124.                 for(j=0; j<NUM; j++)
  125.                 {
  126.                         printf("%c ", *(*(chess+i)+j));
  127.                 }
  128.                 putchar('\n');
  129.         }
  130. }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2015-3-27 21:09:28 | 显示全部楼层
{:1_1:}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2015-5-7 16:20:55 | 显示全部楼层
刚看完这个视频
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-5-26 01:39:17 | 显示全部楼层
感谢额 我看看学习学习
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-5-26 21:48:54 | 显示全部楼层
看看。。。。。。。。。。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2015-5-27 03:04:28 | 显示全部楼层

LZ好人。。。。。。。。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-6-9 17:07:44 | 显示全部楼层
lz好人
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-6-13 10:26:07 | 显示全部楼层
好牛呀
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-6-15 16:52:11 | 显示全部楼层
顶、、、、、、、、、
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-6-17 18:02:32 | 显示全部楼层
sgoyi
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-6-18 14:16:01 | 显示全部楼层
问一下,我用vs2013运行的时候为什么会出现10个错误啊?
WMN9{8)2W7MKB6CZJ(}E4OH.png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-6-19 21:13:30 | 显示全部楼层
为什么运行会出现错误????????
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-6-20 22:23:42 | 显示全部楼层
溯月0503 发表于 2015-6-19 21:13
为什么运行会出现错误????????

你运行的时候有没有错误呢?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-6-21 09:00:36 | 显示全部楼层
秒速五厘米 发表于 2015-6-20 22:23
你运行的时候有没有错误呢?

有呀   你运行了吗
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-6-21 12:24:00 | 显示全部楼层
溯月0503 发表于 2015-6-21 09:00
有呀   你运行了吗

我的错误不是截图了吗?你没看到?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-6-22 09:59:10 | 显示全部楼层
秒速五厘米 发表于 2015-6-21 12:24
我的错误不是截图了吗?你没看到?

好吧   刚看到  我也是   解决了嘛???????????
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-6-23 12:07:50 | 显示全部楼层
菜鸟一个,解决不了!!!靠你了!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-6-23 12:08:21 | 显示全部楼层
溯月0503 发表于 2015-6-22 09:59
好吧   刚看到  我也是   解决了嘛???????????

菜鸟一个,解决不了!!!靠你了!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-6-24 09:03:13 | 显示全部楼层
:sad
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2015-6-24 09:45:20 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-28 01:57

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表