文章标题
来源:互联网 发布:箪食壶浆以迎将军乎 编辑:程序博客网 时间:2024/06/07 02:24
八皇后问题
八皇后问题
回溯法与枚举法
题目简介
八皇后问题是十九世纪著名数学家高斯于1850年提出的。问题是:在8*8的棋盘上摆放8个皇后,使其不能互相攻击,即任意的两个皇后不能处在同意行,同一列,或同意斜线上。可以把八皇后问题拓展为n皇后问题,即在n*n的棋盘上摆放n个皇后,使其任意两个皇后都不能处于同一行、同一列或同一斜线上。
解决冲突:处于同一列或者处于一条对角线上(正负对角线)
(i - j) /(a[i] - a[j]) == 1 或者 (i - j) /(a[i] - a[j]) == -1 或者 a[i] == a[j]
枚举法
思想:八重枚举,枚举出所以摆放的情况(不管合理不合理),然后到第八层for里面判断当前枚举出来的情况是否合理~~~
#include <cstdio>#include <cmath>//位置冲突算法 bool Chongtu(int a[], int n)//a[]位置数组,n皇后个数 { int i = 0, j = 0; for (i = 2; i <= n; ++i)//i:位置 for (j = 1; j <= i-1; ++j)//j:位置 if ((a[i] == a[j]) || (abs(a[i]-a[j]) == i-j))//1:在一行;2:在对角线上 return false; //冲突 return true;//不冲突 }//八皇后:枚举算法 void Queens8(){ int a[9] = {0}; //用于记录皇后位置:(第0行0列我们不用)。如:a[3] = 4;表示第3列第4行位置有皇后 int i = 0,count = 0; //用于计数 for (a[1] = 1; a[1] <= 8; ++a[1]) for (a[2] = 1; a[2] <= 8; ++a[2]) for (a[3] = 1; a[3] <= 8; ++a[3]) for (a[4] = 1; a[4] <= 8; ++a[4]) for (a[5] = 1; a[5] <= 8; ++a[5]) for (a[6] = 1; a[6] <= 8; ++a[6]) for (a[7] = 1; a[7] <= 8; ++a[7]) for (a[8] = 1; a[8] <= 8; ++a[8]) { if (!Chongtu(a,8))//如果冲突,则继续枚举 continue; else { printf("第%d情况:",++count); for (i = 1; i <= 8; ++i) printf("%d ",a[i]);//打印某种情况 printf("\n"); } }}//主函数 int main(){ Queens8(); return 0;}
回溯法(递归版):
#include <cstdio>#include <cmath>int a[9] = {0};int n = 8, count = 0;//位置冲突算法 bool Chongtu(int a[], int n)//a[]位置数组,n皇后个数 { int i = 0, j = 0; for (i = 2; i <= n; ++i)//i:位置 for (j = 1; j <= i-1; ++j)//j:位置 if ((a[i] == a[j]) || (abs(a[i]-a[j]) == i-j))//1:在一行;2:在对角线上 return false; //冲突 return true;//不冲突 }//八皇后问题:回溯算法(递归版) void Queens8(int k) //参数k:递归摆放第k个皇后 { int i = 0; if (k > n) //k>n:即k>8表示最后一个皇后摆放完毕 { printf("第%d种情况:",++count); for (i = 1; i <= n; ++i) printf("%d ",a[i]);//打印情况 printf("\n"); } else //8个皇后未全部摆放完毕 { for (i = 1; i <= n; ++i)//摆放第k个皇后时(转下一行) { //依次从列顶端开始搜索,一直到列底端,直到找到合适位置,如果未找到,自动返回上层递归(回溯) a[k] = i; if (Chongtu(a,k))//不冲突 Queens8(k+1);//递归摆放下一个皇后 } } return;}//主函数 int main(){ Queens8(1);//参数1:表示摆放第1个皇后 return 0;}
回溯法(非递归版):
#include <cstdio>#include <cmath>//位置冲突算法 bool Chongtu(int a[], int n)//a[]位置数组,n皇后个数 { int i = 0, j = 0; for (i = 2; i <= n; ++i)//i:位置 for (j = 1; j <= i-1; ++j)//j:位置 if ((a[i] == a[j]) || (abs(a[i]-a[j]) == i-j))//1:在一行;2:在对角线上 return false; //冲突 return true;//不冲突 }//八皇后问题:回溯法(非递归) void Queens8(){ int n = 8; //8个皇后 int count = 0; //记录当前第几情况 int a[9] = {0}; //存放皇后位置,如:a[2] = 4;表示第2列第4行有一个皇后(a[0]不用) int i = 0,k = 1; //初始化k为第一列 a[1] = 0; //初始化a[1] = 0 while (k > 0) //k==0时:表示摆放第1个皇后就超过了列底部(即已经找完所有情况) { a[k] += 1; //a[k]位置,摆放一个皇后 while ((a[k] <= n) && (!Chongtu(a,k)))//如果a[k](即皇后摆放位置)没有到列最底部,且摆放冲突。 a[k] += 1;//将皇后列下移一位 if (a[k] <= n)//皇后摆放位置没有到达列最底部 { if (k == n)//k==n表示,8列皇后全部摆放完毕 { printf("第%d种情况:",++count); for (i = 1; i <= n; ++i)//打印情况 printf("%d ",a[i]); printf("\n"); } else //皇后还未摆放完毕 { k += 1; //继续摆放下一列 a[k] = 0; //此行初始化a[k] = 0;表示第k列,从第一行开始摆放皇后 } } else //回溯:当a[k]>8进入else,表示在第k列中没有找到合适的摆放位置 k -= 1;//回溯到k-1步:k表示第几个皇后,a[k]表示第k个皇后摆放的位置 } return;}//主函数 int main(){ Queens8(); return 0;}
0 0
- 文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题 文章标题 文章标题 文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题
- 文章标题
- JDBC驱动程序的四种类型
- 常见计算机概念或术语
- POJ 1003 Hangover
- Pull解析器解析XML文件
- mysql体系结构
- 文章标题
- 统计大串中小串出现的次数
- C++ lambda 表达式
- 学习strcpy函数中的问题
- 非常好的理解遗传算法的例子
- 17个学术论文搜索引擎
- [poj3735 Training little cat]【矩阵快速幂】
- 【C语言】猴子吃桃问题
- 第六周项目六 复数模板类(3)