前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【重拾C语言】十二、C语言程序开发(穷举与试探——八皇后问题)

【重拾C语言】十二、C语言程序开发(穷举与试探——八皇后问题)

作者头像
Qomolangma
发布2024-07-30 08:54:20
750
发布2024-07-30 08:54:20
举报
文章被收录于专栏:C语言深度学习

前言

八皇后问题是一个经典的计算机科学问题,要求在一个8×8的棋盘上放置8个皇后,使得它们互相之间不能攻击到对方。这个问题可以通过穷举和试探的方法来解决。

  • 穷举法是一种解决问题的方法,它通过尝试所有可能的解决方案来找到满足条件的解。这种方法适用于解空间较小的问题,例如八皇后问题、0/1 背包问题等。在 C 语言中,我们可以通过编写循环来遍历所有可能的解决方案,并判断是否满足条件。
  • 试探法是一种基于经验或启发式规则的方法,它通过逐步搜索解空间来找到满足条件的解。这种方法适用于解空间较大或问题具有启发式特征的情况。在 C 语言中,我们可以通过编写递归或循环来实现试探法,例如深度优先搜索(DFS)或广度优先搜索(BFS)。

十二、C语言程序开发

12.1~3 自顶向下、逐步求精;结构化程序设计原则;程序风格

【重拾C语言】十二、C语言程序开发(自顶向下、逐步求精;结构化程序设计原则;程序风格)_QomolangmaH的博客-CSDN博客

https://blog.csdn.net/m0_63834988/article/details/133825033?spm=1001.2014.3001.5502 在C语言程序开发中,可以使用自顶向下、逐步求精的方法解决问题,遵循结构化程序设计原则,同时注重良好的程序风格,这可以帮助开发者编写可读性强且易于维护的代码。

12.4 八皇后——穷举与试探

12.4.1 穷举法

穷举法(Exhaustive Search)是一种常见的算法设计方法,用于在给定的搜索空间中尝试所有可能的解决方案,以找到满足特定条件的解。

  • 在C语言中,可以使用循环结构和条件语句来实现穷举法。一般步骤如下:
    • 定义问题的搜索空间和解的表示方式。
    • 使用循环结构遍历搜索空间中的所有可能解。
    • 对于每个可能解,使用条件语句判断是否满足问题的条件。
    • 如果满足条件,执行相应的操作,例如输出结果或保存解决方案。
    • 继续循环,直到遍历完整个搜索空间。
  • 示例:寻找一个整数的平方根
代码语言:javascript
复制
#include <stdio.h>

int main() {
    int num;
    printf("Enter a number: ");
    scanf("%d", &num);

    int i;
    for (i = 0; i <= num; i++) {
        if (i * i == num) {
            printf("Square root of %d is %d\n", num, i);
            break;
        }
    }

    if (i > num) {
        printf("No square root found for %d\n", num);
    }

    return 0;
}

通过循环遍历从0到输入的数字,逐个尝试每个可能的平方根。如果找到一个平方根,就输出结果并结束循环。如果循环结束后仍然没有找到平方根,就输出相应的提示信息。

输出:

这只是一个简单的示例,实际上,穷举法可以应用于各种问题,包括组合优化、密码破解等。但是需要注意的是,穷举法的计算复杂度通常较高,随着搜索空间的增大,计算时间会呈指数级增长。因此,在实际应用中,需要根据问题的规模和要求,权衡计算时间和解的准确性。

12.4.2 试探法

试探法(Backtracking)是一种基于经验或启发式规则的方法,它通过逐步搜索解空间来找到满足条件的解。通常通过递归的方式进行搜索,尝试每一种可能的选择,并在满足条件的情况下继续向下搜索,如果不满足条件,则回溯到上一步选择的状态,重新选择其他可能的路径。

  • 在C语言中,可以使用递归函数和条件语句来实现试探法。一般步骤如下:
    • 定义问题的搜索空间和解的表示方式。
    • 编写一个递归函数,在每一步选择中进行尝试,并根据条件判断是否满足问题的要求。
    • 如果满足条件,执行相应的操作,例如输出结果或保存解决方案。
    • 继续递归调用函数,进入下一步选择。
    • 如果不满足条件,回溯到上一步选择的状态,重新选择其他可能的路径。
    • 继续递归调用函数,进行下一步尝试。
  • 示例:计算给定数字的阶乘
代码语言:javascript
复制
#include <stdio.h>

int factorial(int n) {
    // 基本情况:当 n 为 0 或 1 时,阶乘为 1
    if (n == 0 || n == 1) {
        return 1;
    }
    // 递归情况:调用自身来计算 n 的阶乘
    else {
        return n * factorial(n - 1);
    }
}

int main() {
    int n = 5;
    int result = factorial(n);
    printf("%d 的阶乘为 %d\n", n, result);
    return 0;
}

输出:

试探法可以应用于各种问题,如组合优化、图的遍历、八皇后问题等。通过不断地试探和回溯,可以找到所有可能的解决方案。请注意,试探法的计算复杂度也可能较高,特别是在搜索空间较大时。因此,在实际应用中,需要谨慎选择搜索策略和剪枝技巧,以提高算法的效率。同时,合理设计问题的表示方式和条件判断,可以帮助减少搜索空间,加快求解过程。

12.4.3 穷举与试探(八皇后问题)-递归实现

穷举法是一种简单但低效的解决方法,它通过尝试所有可能的皇后布局来找到满足条件的解。具体步骤如下:

  • 从第一行开始,依次尝试在每一列放置皇后。
  • 检查当前的布局是否满足没有皇后互相攻击的条件。
  • 如果满足条件,继续到下一行,重复上述步骤。
  • 如果在某一行无法找到合适的位置放置皇后,回溯到上一行,尝试下一个列。
  • 当放置完最后一行的皇后并且满足条件时,找到一个解。

穷举法的缺点是需要尝试大量的组合,因此在较大的棋盘上效率较低。

代码语言:javascript
复制
#include <stdio.h>

#define N 8

void printBoard(int board[N][N]) {
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < N; j++) {
            printf("%c ", board[i][j] ? 'Q' : '.');
        }
        printf("\n");
    }
    printf("\n");
}

int isSafe(int board[N][N], int row, int col) {
    // 检查当前位置的左侧是否有皇后
    for (int i = 0; i < col; i++) {
        if (board[row][i]) {
            return 0;
        }
    }

    // 检查当前位置的左上方是否有皇后
    for (int i = row, j = col; i >= 0 && j >= 0; i--, j--) {
        if (board[i][j]) {
            return 0;
        }
    }

    // 检查当前位置的左下方是否有皇后
    for (int i = row, j = col; i < N && j >= 0; i++, j--) {
        if (board[i][j]) {
            return 0;
        }
    }

    return 1;
}
int count = 0; // 全局变量用于计数解的数量
void solveNQueens(int board[N][N], int col) {
    // 所有皇后都放置完毕,打印解决方案,增加解的数量并返回
    if (col == N) {
        printBoard(board);
        count++;
        return;
    }

    // 逐行尝试放置皇后
    for (int i = 0; i < N; i++) {
        if (isSafe(board, i, col)) {
            // 放置皇后
            board[i][col] = 1;

            // 递归地尝试下一列
            solveNQueens(board, col + 1);

            // 回溯,撤销当前位置的皇后
            board[i][col] = 0;
        }
    }
}

int main() {
    int board[N][N] = {0};

    solveNQueens(board, 0);
    printf("Number of solutions: %d\n", count);
    return 0;
}

输出:

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-10-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 十二、C语言程序开发
    • 12.1~3 自顶向下、逐步求精;结构化程序设计原则;程序风格
      • 12.4 八皇后——穷举与试探
        • 12.4.1 穷举法
        • 12.4.2 试探法
        • 12.4.3 穷举与试探(八皇后问题)-递归实现
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档