`
hellobin
  • 浏览: 65504 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

8皇后问题的三种解法

 
阅读更多

算法竞赛入门经典第7章

 

1 生成遍历法:先产生所有的可能,然后根据限制条件过滤结果

 

#define RUN
#ifdef RUN


#include<stdio.h>

//C[x]=y 表示x行的皇后处于y列
int C[50], tot = 0, n = 8, nc = 0;



void search(int cur) {
  int i, j;
  nc++;

  //检查每个可能,看是否会冲突
  if(cur == n) {
    for(i = 0; i < n; i++)
      for(j = i+1; j < n; j++)
        if(C[i] == C[j] || i-C[i] == j-C[j] || i+C[i] == j+C[j]) return;
	//找到一个没冲突的可能
    tot++;
  }
  //遍历生成所有的可能
  else for(i = 0; i < n; i++) {
    C[cur] = i;
    search(cur+1);
  }
}

int main() {
  search(0);
  printf("%d\n", tot);
  printf("%d\n", nc);
  return 0;
}

#endif

 

 

 

2 回溯法

 

//#define RUN
#ifdef RUN

#include<stdio.h>

//C[x]=y 表示x行的皇后处于y列
int C[50], tot = 0, n = 8, nc = 0;

void search(int cur) {

  int i, j;
  nc++;
  //递归边界,只要走到这里,所有的皇后必然不冲突
  if(cur == n) {
    tot++;
  } 
  else {
	  //对于当前第cur行,逐个测试i从0到n-1,看适合放在哪一列
	  for(i = 0; i < n; i++) {
		  int ok = 1;
		  //假设放在第i列
		  C[cur] = i;
		  //测试在前面的行的皇后是否会和当前位置冲突
		  for(j = 0; j < cur; j++){
			  //列冲突,主对角线冲突,副对角线冲突
			  if(C[cur] == C[j] || cur-C[cur] == j-C[j] || cur+C[cur] == j+C[j]) {
				  ok = 0;
				  break;
			  }
		  }
		  //进行下一行的搜索
		  if(ok) search(cur+1);
	  }
  }
  
}

int main() {
  search(0);
  printf("%d\n", tot);
  printf("%d\n", nc);
  return 0;
}

#endif

 

 

3 有全局变量的回溯法(最常用)

 

//#define RUN
#ifdef RUN

#include<stdio.h>
#include <string.h>

//C[x]=y 表示x行的皇后处于y列
int C[50], vis[3][50], tot = 0, n = 8, nc = 0;

void search(int cur) {
  int i, j;
  nc++;
  if(cur == n) {
    tot++;
  } 
  else{
	  //测试每一列
	  for(i = 0; i < n; i++) {
		  //检测列冲突,副对角线,正对角线冲突
		  if(!vis[0][i] && !vis[1][cur+i] && !vis[2][cur-i+n]) {
			  C[cur] = i;
			  vis[0][i] = vis[1][cur+i] = vis[2][cur-i+n] = 1;
			  search(cur+1);
			  vis[0][i] = vis[1][cur+i] = vis[2][cur-i+n] = 0;
		  }
	  }
  }
}

int main() {
  memset(vis, 0, sizeof(vis));
  search(0);
  printf("%d\n", tot);
  printf("%d\n", nc);
  return 0;
}

#endif

 

 

注意:如果在回溯法中使用了辅助的全局变量,则一定要及时把它们恢复原状。例如,若函数有多个出口,则需在每个出口处恢复被修改的值。

分享到:
评论

相关推荐

    八皇后 的三种解法 (java编写)

    一般来说,解决八皇后问题的方法主要有以下三种: 1. **深度优先搜索(DFS)**:这是最常见的解决方法,利用递归的方式,每次尝试在当前行放置一个皇后,并检查是否与前几行的皇后冲突。如果冲突,则回溯到上一行,...

    八皇后问题详细的解法-23页 PPT PDF版.pdf

    ### 八皇后问题详解 ...通过以上分析可以看出,八皇后问题的不同解法各有特点,从简单的枚举算法到高效的回溯法,每种方法都有其适用场景。在实际解决问题时,应根据问题的具体需求选择合适的算法。

    8皇后问题的两种解法(c语言描述)

    ### 8皇后问题的两种解法(C语言描述) #### 方法一:回溯法 **回溯法**是一种通过尝试解决子问题,并且能够“撤销”答案的算法。8皇后问题是一个经典的计算机科学问题,其目标是在一个8×8的棋盘上放置8个皇后,...

    八皇后问题解法(c和c++)

    八皇后问题的两种解法,包含c方式和c++方式

    8皇后解法 八皇后解法

    比较经典的8皇后问题 与大家共享比较经典的8皇后问题 与大家共享比较经典的8皇后问题 与大家共享

    八皇后问题的一种解法(C语言源代码)

    这个是八皇后问题的一种解法,希望可以给大家参考,有需要的话可以看一下哦!

    八皇后问题的java解法.rar

    八皇后问题的java解法.rar

    N皇后问题解法

    算法设计中的皇后摆放问题,用C写的八皇后和N皇后的解法。

    n皇后问题解法

    解决n皇后的代码 #include #include #include #define _PRINT_ 0//没有输出具体的解,只是计算了总数。 #define MAXQ 100 long N, t; long qx[MAXQ], qy[MAXQ]; long quse; /* */ bool chk(int x, int y) //...

    八皇后问题详细的解法.ppt

    八皇后问题详细的解法.ppt

    N皇后问题的各种解法

    N皇后问题是一个经典的计算机科学问题,它涉及到在N×N的棋盘上放置N个皇后,使得皇后之间不能互相攻击,即任何两个皇后都不能处于同一行、同一列或同一斜线上。这个问题通常用来演示和理解各种算法,如回溯、迭代法...

    n皇后问题正确解法.txt

    n皇后问题正确解法.txt

    八皇后问题的scheme解法(queen8.scm)

    收集的用scheme语言编写的八皇后的解法,对学习scheme语言想理解递归的同志们是一个好例子,sicp中也有此练习题。

    八皇后问题

    八皇后问题,回溯算法,92种解法均有,且结果真观易懂

    八皇后问题详细的解法PPT课件.ppt

    八皇后问题详细的解法PPT课件.ppt

    八皇后问题c++解法

    ### 八皇后问题C++解法详解 #### 一、八皇后问题简介 八皇后问题是一个经典的计算机科学问题,最早由国际象棋爱好者马克斯·贝瑟尔在1848年提出。该问题要求在8×8的国际象棋棋盘上放置八个皇后,使得任意两个皇后...

    八皇后问题C解法

    该问题要求在一个8×8的国际象棋棋盘上放置八个皇后,使得任意两个皇后都不在同一行、同一列或同一对角线上。这是一个典型的组合问题,涉及排列与组合的数学原理。 #### 解决方案分析 给定代码片段提供了一个基于...

    八皇后问题详细的解法PPT学习教案.pptx

    八皇后问题详细的解法PPT学习教案.pptx

    八皇后问题C语言解法

    ### 八皇后问题C语言解法 #### 一、八皇后问题概述 八皇后问题是一个经典的问题,在棋盘上放置八个皇后,要求任何两个皇后不能处于同一行、同一列或同一对角线上。该问题可以扩展到任意大小的棋盘(N皇后问题),...

Global site tag (gtag.js) - Google Analytics