分治算法 - 八皇后

是一个以国际象棋为背景的问题:如何能够在 8×的国际象棋棋盘上放置八个皇后,使得任何一个皇后都无法直接吃掉其他的皇后?为了达到此目的,任两个皇后都不能处于同一条横行、纵行或斜线上。八皇后问题可以推广为更一般的n皇后摆放问题:这时棋盘的大小变为n×n,而皇后个数也变成n当且仅当 n = 1  n  4 时问题有解。

  1. /* 
  2. * Copyright (c) leo 
  3. * All rights reserved. 
  4. * filename: nQueens
  5. * summary : 
  6. * version : 1.
  7. * author : leo 
  8. * date : 8.12.2011 
  9. *问题:
  10. *    在n*(n=or n>=)的棋盘上放置n个皇后,如果在同一行,同一列,同一对角线上都不存在两个皇后,
  11. *    那么这个棋盘格局就是n皇后的一个解。
  12. *要求:
  13. *    找出n皇后的一组解即可,打印出放置满足n皇后条件的棋子位置
  14. */
  15. #include<stdio.h>
  16. #include<math.h>
  17. #include<stdlib.h>
  18. #include<conio.h>
  19. #define N 8 //皇后数=棋盘行列数
  20. int a[N]; //a[i]为第i行皇后所在列
  21. void show() //图形化输出
  22. {
  23.     int i;
  24.     int p,;
  25.     int b[N][N]={0};
  26.     static t=1;
  27.     printf("第%d个解为: ",t++);
  28.     for(i=0;i<N;i++)
  29.     {
  30.         b[i][a[i]]=1;
  31.         printf("(%d,%d) ",i,a[i]);
  32.     }
  33.     printf("\n");
  34.     for(p=0;p<N;p++)
  35.     {
  36.         for(q=0;q<N;q++)
  37.         {
  38.             if(b[p][q]==1)
  39.                 printf("●");
  40.             else
  41.                 printf("○");
  42.         }
  43.         printf("\n");
  44.     }
  45. }
  46. int check(int n) //满足条件返回1,否则返回0
  47. {
  48.     int i;
  49.     for(i=0;i<n;i++)
  50.     {
  51.         if(a[i]==a[n]||fabs(n-i)==fabs(a[i]-a[n])) //at the same column or diagonal (对角线)
  52.             return 0;
  53.     }
  54.     return 1;
  55. }
  56. void put(int n) //在第n行放置第n个皇后
  57. {
  58.     int i;
  59.     if(n==N)
  60.         return ;
  61.     for(i=0;i<N;i++)
  62.     {//此处循环一直到N,循环,嵌套
  63.         a[n]=i;
  64.         if(check(n)) //位置合法
  65.         {
  66.             if(n==N-1) //皇后全部放置完毕
  67.                 show();
  68.             else
  69.                 put(n+1);
  70.         }
  71.     }
  72. }
  73. int main ()
  74. {
  75.     put(0);
  76.     return 0;
  77. }

8皇后问题JAVA算法 用递归实现,程序种有两种判定皇后可放的方法 一种采用辅助数组,一种采用斜率判断 代码比较简洁,对递归的理解和掌握有帮助 测试结果: 1 :1 5 8 6 3 7 2 4 2 :1 6 8 3 7 4 2 5 3 :1 7 4 6 8 2 5 3 4 :1 7 5 8 2 4 6 3 5 :2 4 6 8 3 1 7 5 6 :2 5 7 1 3 8 6 4 7 :2 5 7 4 1 8 6 3 8 :2 6 1 7 4 8 3 5 9 :2 6 8 3 1 4 7 5 10 :2 7 3 6 8 5 1 4 11 :2 7 5 8 1 4 6 3 12 :2 8 6 1 3 5 7 4 13 :3 1 7 5 8 2 4 6 14 :3 5 2 8 1 7 4 6 15 :3 5 2 8 6 4 7 1 16 :3 5 7 1 4 2 8 6 17 :3 5 8 4 1 7 2 6 18 :3 6 2 5 8 1 7 4 19 :3 6 2 7 1 4 8 5 20 :3 6 2 7 5 1 8 4 21 :3 6 4 1 8 5 7 2 22 :3 6 4 2 8 5 7 1 23 :3 6 8 1 4 7 5 2 24 :3 6 8 1 5 7 2 4 25 :3 6 8 2 4 1 7 5 26 :3 7 2 8 5 1 4 6 27 :3 7 2 8 6 4 1 5 28 :3 8 4 7 1 6 2 5 29 :4 1 5 8 2 7 3 6 30 :4 1 5 8 6 3 7 2 31 :4 2 5 8 6 1 3 7 32 :4 2 7 3 6 8 1 5 33 :4 2 7 3 6 8 5 1 34 :4 2 7 5 1 8 6 3 35 :4 2 8 5 7 1 3 6 36 :4 2 8 6 1 3 5 7 37 :4 6 1 5 2 8 3 7 38 :4 6 8 2 7 1 3 5 39 :4 6 8 3 1 7 5 2 40 :4 7 1 8 5 2 6 3 41 :4 7 3 8 2 5 1 6 42 :4 7 5 2 6 1 3 8 43 :4 7 5 3 1 6 8 2 44 :4 8 1 3 6 2 7 5 45 :4 8 1 5 7 2 6 3 46 :4 8 5 3 1 7 2 6 47 :5 1 4 6 8 2 7 3 48 :5 1 8 4 2 7 3 6 49 :5 1 8 6 3 7 2 4 50 :5 2 4 6 8 3 1 7 51 :5 2 4 7 3 8 6 1 52 :5 2 6 1 7 4 8 3 53 :5 2 8 1 4 7 3 6 54 :5 3 1 6 8 2 4 7 55 :5 3 1 7 2 8 6 4 56 :5 3 8 4 7 1 6 2 57 :5 7 1 3 8 6 4 2 58 :5 7 1 4 2 8 6 3 59 :5 7 2 4 8 1 3 6 60 :5 7 2 6 3 1 4 8 61 :5 7 2 6 3 1 8 4 62 :5 7 4 1 3 8 6 2 63 :5 8 4 1 3 6 2 7 64 :5 8 4 1 7 2 6 3 65 :6 1 5 2 8 3 7 4 66 :6 2 7 1 3 5 8 4 67 :6 2 7 1 4 8 5 3 68 :6 3 1 7 5 8 2 4 69 :6 3 1 8 4 2 7 5 70 :6 3 1 8 5 2 4 7 71 :6 3 5 7 1 4 2 8 72 :6 3 5 8 1 4 2 7 73 :6 3 7 2 4 8 1 5 74 :6 3 7 2 8 5 1 4 75 :6 3 7 4 1 8 2 5 76 :6 4 1 5 8 2 7 3 77 :6 4 2 8 5 7 1 3 78 :6 4 7 1 3 5 2 8 79 :6 4 7 1 8 2 5 3 80 :6 8 2 4 1 7 5 3 81 :7 1 3 8 6 4 2 5 82 :7 2 4 1 8 5 3 6 83 :7 2 6 3 1 4 8 5 84 :7 3 1 6 8 5 2 4 85 :7 3 8 2 5 1 6 4 86 :7 4 2 5 8 1 3 6 87 :7 4 2 8 6 1 3 5 88 :7 5 3 1 6 8 2 4 89 :8 2 4 1 7 5 3 6 90 :8 2 5 3 1 7 4 6 91 :8 3 1 6 2 5 7 4 92 :8 4 1 3 6 2 7 5
C语言中的分治算法通常用于解决复杂的问题,比如著名的八皇后问题(n皇后问题),它是一个经典的回溯法问题,不是直接的分治策略。但是,可以借助递归的思想来简化问题。八皇后问题的目标是在一个n×n的棋盘上放置n个皇后,使得任意两个皇后都不在同一行、同一列以及对角线上。 分治法在这里并不适用,因为它更适合于将大问题分解成相互独立且规模较小的子问题,然后分别解决并合并结果。对于n皇后问题,我们可以采用迭代的方式,利用一个数组或二维数组记录每一行皇后的位置,然后依次尝试每行的每一个位置,检查是否满足条件,如果满足则前进到下一行,如果不满足则回溯到上一行继续尝试其他位置,直到所有皇后都放好为止。 以下是简单的C语言代码示例: ```c #include <stdio.h> #define N 8 // 可以改变这个值以适应不同大小的棋盘 int isSafe(int row, int col, int chessboard[N][N]) { // 检查列冲突和左上对角线冲突 for (int i = 0; i < row; i++) { if (chessboard[i][col] == 1 || chessboard[row - i - 1][col - i] == 1) return 0; } return 1; } void solveNQueens(int row, int chessboard[N][N], int solved) { if (row == N) { // 如果所有皇后都放置完毕,打印解决方案 for (int i = 0; i < N; i++) printf("%d ", chessboard[i]); printf("\n"); solved++; } else { for (int col = 0; col < N; col++) { if (isSafe(row, col, chessboard)) { chessboard[row][col] = 1; // 放置皇后 solveNQueens(row + 1, chessboard, solved); chessboard[row][col] = 0; // 回溯 } } } } int main() { int chessboard[N][N]; int solutions = 0; solveNQueens(0, chessboard, solutions); printf("共有 %d 种解法\n", solutions); return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值