zoukankan      html  css  js  c++  java
  • B

    一天课下,张老板研究起了国际象棋,渴望完美的他更改了棋盘的大小,在N*N的方格棋盘放置了N个皇后,希望它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在与棋盘边框成45角的斜线上) 
    张老板把这个艰巨的任务交给了你,对于给定的N,求出有多少种合法的放置方法。 

    Input共有若干行,每行一个正整数N≤10,表示棋盘和皇后的数量;如果N=0,表示结束。Output共有若干行,每行一个正整数,表示对应输入行的皇后的不同放置数量。Sample Input

    1
    8
    5
    0

    Sample Output

    1
    92
    10

    第一次看到这个题感觉很难,后来通过看视频学会了一种递归算法来解这道问题,想明白后还是很有意思的,不过递归是一种很低效的算法,提交的时候TEL了,正确的解法应该是用回溯算法,以后有时间再理解

    递归算法(低效)

    #include<stdio.h>
    #include<string.h>
    
    int count = 0;
    int t;
    
    int notDanger(int row, int j, int (*arr)[10])
    {
        int flag1, flag2, flag3, flag4, flag5;
        int i, k;
    
        flag1 = flag2 = flag3 = flag4 = flag5 = 0;
    
        //判断列是不是危险
        for( i = 0; i < t; i++ )
        {
            if(arr[i][j] == 1)
            {
                flag1 = 1;
                break;
            }
        }
    
        //判断左上方
        for( i = row, k = j; i >= 0 && k >= 0; i--, k-- )
        {
            if(arr[i][k] == 1)
            {
                flag2 = 1;
                break;
            }
        }
    
        //判断左下方
        for( i = row, k = j; i < t && k >= 0; i++, k-- )
        {
            if(arr[i][k] == 1)
            {
                flag3 = 1;
                break;
            }
        }
    
        //判断右上方
        for( i = row, k = j; i >= 0 && k < t; i--, k++ )
        {
            if(arr[i][k] == 1)
            {
                flag4 = 1;
                break;
            }
        }
    
        //判断右下方
        for( i = row, k = j; i < t && k < t; i++, k++ )
        {
            if(arr[i][k] == 1)
            {
                flag5 = 1;
                break;
            }
        }
    
        if(flag1 == 1 || flag2 == 1 || flag3 == 1 || flag4 == 1 || flag5 == 1)
            return 0;
    
        else
            return 1;
    }
    
    void nQueen(int row, int n, int (*arr)[10])
    {
        int arr2[10][10], i, j;
    
        for( i = 0; i < n; i++ )
        {
            for( j = 0; j < n; j++ )
            {
                arr2[i][j] = arr[i][j];
            }
        }
    
        if(row == n)
            count++;
    
        else
        {
            //该位置没有危险
            for( j = 0; j < n; j++ )        //这一部分代码其实往下会产生很大的容量
            {                                       //有时候自己会在这部分,搞混。
                if(notDanger(row, j, arr))
                {
                    for( i = 0; i < n; i++ )
                    {
                        arr2[row][i] = 0;
                    }
    
                    arr2[row][j] = 1;
    
                    nQueen(row+1, n, arr2);
                }
            }
        }
    }
    
    int main()
    {
        int arr[10][10], i, j;
    
        while(scanf("%d", &t) != EOF && t)
        {
            count = 0;
    
            for( i = 0; i < t; i++ )
            {
                for( j = 0; j < t; j++ )
                {
                    arr[i][j] = 0;
                }
            }
    
            nQueen(0, t, arr);
            if(count == 0)
                printf("None
    ");
            else
                printf("%d
    ", count);
        }
    
        return 0;
    }                            

    回溯算法

    #include<stdio.h>
    #include<string.h>
    
    int n,tmp;
    int map[11];
    
    void DFS(int k)
    {
        int i,j,flag;
        if(k==n+1)
        {
            tmp++;
            return;
        }
        else
        {
            for(i=1;i<=n;++i)
            {
                map[k]=i;
                flag=1;
                for(j=1;j<k;++j)
                {
                    if(map[j]==i||i-k==map[j]-j||i+k==map[j]+j)   // 注:1、i=map[k]  2、不在同一条斜线的两点的含义是行标到对角线的的距离不相等
                    {
                        flag=0;
                        break;
                    }
                }
                if(flag)
                    DFS(k+1);
            }
        }
    }
    
    int main()
    {
        int i,m;
        int ans[11];
        for(n=1;n<=10;++n)
        {
            tmp=0;
            DFS(1);
            ans[n]=tmp;
        }
        while(scanf("%d",&m),m)
        {
            printf("%d
    ",ans[m]);
        }
        return 0;
    }
    View Code
    永远渴望,大智若愚(stay hungry, stay foolish)
  • 相关阅读:
    linux--->curl
    linux--->定时任务
    php--->无限级分类
    php--->自己封装的简易版mvc框架
    php--->单例模式封装mysql操作类
    Linux使用退格键时出现^H ^?解决方法
    错误日志
    linux下redis服务器安装使用 安装php的redis扩展 安装laravel下的redis
    php system()
    laravel redis的使用
  • 原文地址:https://www.cnblogs.com/h-hkai/p/8150572.html
Copyright © 2011-2022 走看看