n后问题

在n*n的棋盘上放置彼此不受攻击的n个皇后,按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。n后问题等价于在n*n格的棋盘上放置n个皇后,任何2个皇后不放在同一行或同一列或同一斜线上。共有多少中放法?

1.回溯法

#include <stdio.h>
#include <stdlib.h>

int *x;
int n;
int sum;

int place(int k)
{
    for (int i = 1; i < k; i++) {
        if (x[i] == x[k] || abs(x[i] - x[k]) == abs(i - k)) {
            return 0;
        }
    }
    return 1;
}

void backtrack(int t)
{
    if (t > n) sum++;
    else
    {
        for (int i = 1; i <= n; i++) {
            x[t] = i;
            if (place(t)) {
                backtrack(t+1);
            }
        }
        
    }
}

int main()
{
    printf("请输入n的值:\n");
    scanf("%d", &n);
    
    int a[n+1];
    x = a;
    
    sum = 0;
    backtrack(1);
    
    printf("当n = %d时,共有%d种不同的放置方法.", n, sum);
    
    return 0;
}


2. 暴力求解

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int main(int argc, const char * argv[])
{
    int num, n;
    int count = 0;
    int *x;
    
    printf("请输入n的值:\n");
    scanf("%d", &n);
    
    int a[n+1];
    x = a;
    
    for (num = 0; num < pow(4, 4); num++) {
        int j = num;
        for (int i = 0; i < n; i++) {
            x[i] = j % n;
            j = j / n;
        }
        
        int k = 1;
        for (int i = 0; i < n; i++) {
            for (j = i + 1; j < n; j++) {
                if (a[i] == a[j] || abs(i - j) == abs(a[i] - a[j])) {
                    k = 0;
                }
            }
        }
        
        if (k) {
            count++;
        }
    }
    
    printf("当n = %d时,共有%d中不同的放置方法.\n", n, count);

    return 0;
}





版权声明:本文为博主原创文章,未经博主允许不得转载。

posted on 2015-10-21 23:58  ll_xyls  阅读(163)  评论(0编辑  收藏  举报