zoukankan      html  css  js  c++  java
  • N皇后问题

    要求:在一个N*N的棋盘上放置N个皇后,每行一个并使其不能互相攻击(同一行、同一列、同一斜线上的皇后都会自动攻击)。

    代码概述:

    先写一个检测是否能放皇后的函数,还有一个输出函数

    再写一个函数为执行试探的步骤

    在该函数中:

    对于合格的位置进行放置皇后检验:如果可以放置,则进行到下一行的第一个位置;如果不能放置则进行到该行的下一个位置

    对于不合格的位置,分为两种情况:

    1、行数超出:输出这种放置皇后的棋局

    2、列数超出;

    进行回退,将上一行的皇后往后挪一个位置进行检验

    #include "iostream"  
    #include "cmath"  
    using namespace std;  
      
    #define Max 20      //定义棋盘的最大值  
    int a[Max];  
    int show(int S)    //定义输出函数  
    {  
        int i,p,q;  
        int b[Max][Max]={0};     //定义并初始化b[][]输出数组  
      
        for(i=1;i<=S;i++)    //按横列i顺序输出a[i]数组坐标  
        {  
            b[i][a[i]]=1;  
            printf("(%d,%d)	",i,a[i]);  
        }  
        printf("
    ");  
        for(p=1;p<=S;p++)     //按棋盘的横列p顺序标明皇后的位置  
        {  
            for(q=1;q<=S;q++)  
            {  
                if(b[p][q]==1)     //在第p行第q列放置一个皇后棋子  
                    printf("");  
                else  
                    printf("");  
            }  
            printf("
    ");  
        }  
        return 0;  
    }  
      
    int check(int k)    //定义check函数  
    {  
        int i;  
        for(i=1;i<k;i++)    //将第k行与前面的第1~~k-1行进行判断  
        {  
            if((a[i]==a[k]) || (a[i]-a[k]==k-i) || (a[i]-a[k]==i-k))    //检查是否有多个皇后在同一条直线上  
            {  
                return 0;  
            }  
        }  
        return 1;  
    }  
      
    void check_m(int num)    //定义函数  
    {  
        int k=1,count=0;  
        printf("The possible configuration of N queens are:
    ");  
        a[k]=1;  
        while(k>0)  
        {  
            if(k<=num && a[k]<=num)    //从第k行第一列的位置开始,为后续棋子选择合适位子  
            {  
                if(check(k)==0)    //第k行的a[k]列不能放置皇后  
                {  
                    a[k]++;        //继续探测当前行的下一列:a[k]+1  
                }  
                else  
                {  
                    k++;         //第K行的位置已经确定了,继续寻找第k+1行皇后的位置  
                    a[k]=1;      //从第一列开始查找  
                }  
            }  
            else  
            {  
                if(k>num)     //若满足输出数组的要求则输出该数组  
                {  
                    count++;  
                    printf("[%d]:  ",count);  
                    show(num);    //调用输出函数show()  
                }  
                //如果k>num会执行下面两行代码,因为虽然找到了N皇后问题的一个解,但是要找的是所有解,需要回溯,从当前放置皇后的下一列继续探测  
                //如果a[k]>num也会执行下面两行代码,就是说在当前行没有找到可以放置皇后的位置,于是回溯,从上一行皇后位置的下一列继续探测  
                k--;      //棋子位置不符合要求,则退回前一步  
                a[k]++;   //继续试探下一列位置  
            }  
        }  
        printf("The count is: %d 
    ",count);  
    }  
      
    int main(void)  
    {  
        int N,d;  
        //system("color 2a");  
        do  
        {  
            printf("********************N皇后问题系统*********************
    
    ");  
            printf("                  1. 四皇后问题                        
    ");  
            printf("                  2. 八皇后问题                        
    ");  
            printf("                  3. N 皇后问题(N<20)                  
    ");  
            printf("                  4. 退出                              
    ");  
            printf("******************************************************
    ");  
            printf("
        从数字1-4之间的数选择需要的操作
    
    "); /*提示输入选项*/  
            printf("      请输入你要选择的功能选项:__
    ");  
            scanf("%d",&d);   
            switch(d)  
            {  
            case 1:  
                check_m(4);      //4皇后问题  
                break;   
            case 2:  
                check_m(8);     //8皇后问题  
                break;   
            case 3:  
                printf("请输入N的值:_");  
                fflush(stdin);      //清除缓冲  
                scanf("%d",&N);  
                printf("
    ");  
                if(N>0&&N<20)  
                {  
                    check_m(N);    //N皇后问题  
                    break;  
                }  
                else  
                {  
                    printf("输入错误,请从新输入:");  
                    printf("
    
    ");  
                    break;   
                }  
            case 4:  
                exit(0);     //程序结束  
            }  
        }while(1);  
        system("pause");  
        return 0;  
    }  

    具体原理可以参见http://blog.csdn.net/hackbuteer1/article/details/6657109

  • 相关阅读:
    ie下table无法设置宽度的坑,解决方案:在td里面添加div把td宽度撑开即可。
    js simple drag.
    javascript事件捕获机制,dom tree
    WPF,布局,Menu,MenuItem,DockPanel,Grid,DockPanel.Dock='',ToolBar,Content,Image,Uri
    .net IntPtr ==interoperable pointer
    Why do I keep getting mixed tabs and spaces in a Visual Studio C# code window?[vs power tools issue transfered]
    vs nuget package control.
    Introduction to the WinPcap Networking Libraries
    读懂这一篇,集群节点不下线
    函数组合的 N 种模式
  • 原文地址:https://www.cnblogs.com/denghui666/p/7247452.html
Copyright © 2011-2022 走看看