八皇后和全排列

经典的递归程序设计中的2到题目

1、八皇后问题

国际象棋棋盘走法,用递归实现所有的可能性;

棋盘:

(1)、代码如下:

#include<stdio.h>

typedef unsigned char boolean;

#define TRUE        1
#define FALSE        0

#define EIGHT    8

void showChess(int (*chess)[EIGHT]);  //显示棋盘
boolean isSafe(int (*chess)[EIGHT], int row, int col); //判断这个位置是否安全
void eightQueen(int (*chess)[EIGHT], int row);  //八皇后的递归程序

void eightQueen(int (*chess)[EIGHT], int row){
    int colIndex;
    
    if(row >= EIGHT){
        showChess(chess);
    }else{
        for(colIndex = 0; colIndex < EIGHT; colIndex++){
            if(isSafe(chess, row, colIndex) == TRUE){
                chess[row][colIndex] = 1;
                eightQueen(chess, row+1);
                chess[row][colIndex] = 0;
            }
        }
    }
}

boolean isSafe(int (*chess)[EIGHT], int row, int col){
    int rowIndex;
    int colIndex;

    for(rowIndex = row-1; rowIndex >= 0; rowIndex--){
        if(chess[rowIndex][col] == 1){
            return FALSE;
        }
    }
    for(rowIndex = row-1, colIndex = col-1; rowIndex >= 0 && colIndex >= 0; rowIndex--, colIndex--){
        if(chess[rowIndex][colIndex] == 1){
            return FALSE;
        }
    }
    for(rowIndex = row-1, colIndex = col+1; rowIndex >= 0 && colIndex < EIGHT; rowIndex--, colIndex++){
        if(chess[rowIndex][colIndex] == 1){
            return FALSE;
        }
    }

    return TRUE;
}

void showChess(int (*chess)[EIGHT]){
    int i;
    int j;
    int static count;

    printf("解:%d\n", ++count);
    for(i = 0; i < EIGHT; i++){
        for(j = 0; j < EIGHT; j++){
            printf("%4d ", chess[i][j]);
        }
        printf("\n");
    }
}

void main(void){
    int chess[EIGHT][EIGHT] = {0};

    eightQueen(chess, 0);
}

(2)、运行结果:

因为4个方向,每一个方向都有23种解法!!!

2、全排列问题

从n个数据中挑选m个数据,每个数据只能取一次,输出其全部组合的可能性;

(1)、代码如下:

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

void fullArray(char *sourceStr, int sourceLen, int *used, int i, char *resStr, int count);

void fullArray(char *sourceStr, int sourceLen, int *used, int i, char *resStr, int count){
    int index;

    if(i >= count){
        printf("%s\n", resStr);
    }else{
        for(index = 0; index < sourceLen; index++){
            if(used[index] == 0){
                resStr[i] = sourceStr[index];
                used[index] = 1;
                fullArray(sourceStr, sourceLen, used, i+1, resStr, count);
                used[index] = 0;
            }
        }
    }
}

void main(void){
    char sourceStr[80];
    int used[80] = {0};
    char resStr[80] = {0};
    int count;

    printf("请输入字符串: ");
    gets(sourceStr);
    printf("请问要几个进行全排列? ");
    scanf("%d", &count);

    fullArray(sourceStr, strlen(sourceStr), used, 0, resStr, count);
}

(2)、运行结果:

时间: 2024-12-16 04:37:51

八皇后和全排列的相关文章

LeetCode 31:递归、回溯、八皇后、全排列一篇文章全讲清楚

本文始发于个人公众号:TechFlow,原创不易,求个关注 今天我们讲的是LeetCode的31题,这是一道非常经典的问题,经常会在面试当中遇到.在今天的文章当中除了关于题目的分析和解答之外,我们还会详细解读深度优先搜索和回溯算法,感兴趣的同学不容错过. 链接 Next Permutation 难度 Medium 描述 实现C++当中经典的库函数next permutation,即下一个排列.如果把数组当中的元素看成字典序的话,那下一个排列即是字典序比当前增加1的排列.如果已经是字典序最大的情况

《编程之法》1.3字符串的全排列,组合,重复排列,八皇后问题

题目描述:输入一个字符串,打印出该字符串中字符的所有排列,例如输入"abc",输出"abc","acb","bac","bca","cab","cba" 解法一:递归实现 类似于图的深度遍历搜索求全路径的算法,每次交换两个数,并输出,按照递归的方法,如求abcd的全排序,1:先求abcd后面的bcd全排列(同样先求b后面cd的全排列,然后b与后面的元素依次交换);2:

八皇后问题 (全排列的运用)

8皇后问题相信大家都听说过: 在一个8*8格子的矩形里,放上8个皇后,如果在同一直线上(横,竖,(左右)斜线)存在两个皇后,他们就互相攻击了,现在要我们来求一共有多少种摆法,让他们相安无事! 一般的解法都是回溯法,一步一步的试探,不行就返回再来,这样做时间效率很低,2的64次方, 今天我介绍的是全排列法解此题: 我们可以把这个问题抽象出来: 1.序号为0-7的8个皇后: 2.放置到序号为0-7的8个箱子里: 3.同时所有皇后的序号与箱子序号的和各不相同: 4.所有皇后的序号与箱子序号的差也各不相

【剑指offer】八皇后问题

转载请注明出处:http://blog.csdn.net/ns_code/article/details/26614999 剑指offer上解决八皇后问题,没实用传统的递归或非递归回溯法,而是用了非常巧妙的全排列法. 先说下八皇后问题:在8 X 8的国际象棋上摆放八个皇后,使其不能相互攻击,即随意两个皇后不得处于同一行,同一列或者允许对角线上,求出全部符合条件的摆法. 全排列解决八皇后问题的思路例如以下: 因为8个皇后不能处在同一行,那么肯定每一个皇后占领一行,这样能够定义一个数组A[8],数组

八皇后问题解析

今天下午思考了几个小时,最后还是选择走.net,虽然java现在很火,但毕竟学了一学期c#了,本人还是比较细化wp的,所以最后选择了.net.我相信只要学精,不管以后就业如何,都应该差不到哪去. 不扯远了,现在就来说一说八皇后问题.现在我还是大三学生,前几周上java实验课的时候我们实现了全排列问题,还剩一节课,老师就讲了下八皇后问题(就是在8x8的棋盘上,八个皇后两两不能在一条直线上),当时上课没认真听,下课去看有点看不懂,后来去看了其他博主的博文,更是看不懂,最后还是看老师写的代码.细细审看

54. 八皇后问题[eight queens puzzle]

[本文链接] http://www.cnblogs.com/hellogiser/p/eight-queens-puzzle.html [题目] 在8×8的国际象棋上摆放八个皇后,使其不能相互攻击,即任意两个皇后不得处在同一行.同一列或者同一对角斜线上.下图中的每个黑色格子表示一个皇后,这就是一种符合条件的摆放方法.请求出总共有多少种摆法. [分析] 之前博文28.字符串的排列[StringPermutation]介绍过字符串的全排列,八皇后问题也可以转换为全排列问题. 由于八个皇后的任意两个不

字符串排列与八皇后问题

字符串排列问题 输入一个字符串,输出该字符串的所有排列.如输入abc,则输出abc,acb,bca,caab,cba.根据排列组合的知识,3个字符串的排列有3!=6个. 先考虑字符没有重复的情况: 可以将字符分成两个部分,第一部分为第一个字符,第二部分为后面的部分. 这样abc的排列情况可以这么分析: a+bc; b+ac; c+ab; 即将第一个字符一次与后面的每一个字符交换,然后分别求剩余部分的排列.这种思想将原来为n的问题变成了n-1的问题.用递归实现: 下面是<剑指offer上的代码>

递归 八皇后

递归 八皇后 题意 > 棋子不能在同一行,同一列,以及同一对角线. > 输出所有符合要求的情况. 步骤:用计数器统计次数,按列写出全排列,再枚举任意两个棋子,如果不符合条件,则计数器不变. #include <cstdio> #include <algorithm> const int maxn = 100; int n, p[maxn], hashTable[maxn] = {false}; int count = 0; void generateP(int inde

回溯 八皇后

回溯 八皇后 题意 > 棋子不能在同一行,同一列,以及同一对角线. > 输出所有符合要求的情况. 步骤:用计数器统计次数,按列写出全排列,再枚举任意两个棋子,如果不符合条件,则计数器不变.与直接递归不同的是,用到了剪枝技巧,如果不符合要求,则立即开始下一个状况 #include <cstdio> #include <algorithm> const int maxn = 100; int n, p[maxn], hashTable[maxn] = {false}; in