今天,来尝试一下用递归实现错排问题。

  1. (常考点) 递归关系:D(n)=(n-1)(D(n-1)+D(n-2)) 特别地有D(1)=0,D(2)=1;

  2. 错排公式:D(n) = n! [(-1)^2/2! + … + (-1)^(n-1)/(n-1)! + (-1)^n/n!], 特别地有0!=1 1!=1 代码实现:

//用递归方式输出错排序列
#include <stdio.h>
#define N 100

int  a[N] = { 0 };//存放错排序列
int flag[N] = { 0 };//用于标志某元素是否被使用
int n, count = 0;

void Recursion(int x)
{
    //若1..n位均已成功放置 
    if (x > n)
    {
        count++;

        //输出得到的错排
        for (int i = 1; i <= n; i++)
            printf("%d  ", a[i]);
        printf("\n");
        return;
    }
    else
    for (int i = 1; i <= n; i++)
    {
        //若i可以放置在x位 
        if (flag[i] == 0 && x != i)//没被使用过
        {
            flag[i] = 1;    //做放置标记 
            a[x] = i;		//放置 
            Recursion(x + 1);   //尝试放置x+1位 
            flag[i] = 0;        //撤销放置标记 
        }
    }
}

int main() {
    int i;

    printf("input n:");
    scanf_s("%d", &n);

    //从1位开始尝试得到序列1..n的错排 
    Recursion(1);

    printf("count:%d\n", count);

    return 0;
}