zoukankan      html  css  js  c++  java
  • N皇后演示程序

    问题描述:

    N×N格的棋盘上放置彼此不受攻击的N个皇后,按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子,求解可以放置的布局方式。

    设计要求:

    (1) 要求实现图形化棋盘显示;

    (2) 要求实现N皇后布局演示,可以使用方向键进行布局切换。

    问题分析:

    当n的个数比较小时,我们可以采用穷举法来列举可能出现的情况,但当n的个数比较大时,就需要考虑其他的方法了。在n*n的棋盘上,每个皇后可能有n个摆放位置,有两种方法可以来进行判断:

    1.最后一个皇后已经放到棋盘,此时在进行判断是否满足条件。

    2.每放一个皇后就进行判断,当不满足条件时,后面的情况就不用再考虑了,直接看下一个摆放的位置。

    如下图:

    因此我们就可以得到解题思路,每放一个皇后就与上一个进行判断,判断该位置是否与前面的皇后发生冲突。

    算法实现:

    #include<cmath>
    using namespace std;
    int n,tol=0; // N皇后个数和成功个数
    int queen[100] = {0};  //[]里的值代表行数,value值代表列数
    int col[1000][100] = {0};  //用来存放成功的数据
    bool check(int r,int c){ // (r,c)代表新皇后的坐标
        for(int i=0;i<r;i++){
            if(queen[i]==c||(abs(queen[i]-c) == abs(r-i))){ // 判断是否冲突(第一个判断的是行数等于列数,即对角线)
                return false;
            }
        }
        return true;
    }
    void DFS(int r){
        if(r==n){ //判断最后一个是否已经放到棋盘,最后一个放到棋盘,说明是一种解法
            for(int i=0;i<n;i++){
                col[tol][i] = queen[i]; //讲棋盘存到总的期盼里
            }
            tol++; //成功次数++
            //queen[100]={}; //初始临时棋盘
            return;
        }
    
        for(int c=0;c<n;c++){
            if(check(r,c)){  //判断该位置是否与前n-1个位置冲突
                queen[r] = c; //不冲突赋值
                DFS(r+1); //进行一下行操作
            }
        }
    }
    void show(int r){
        for(int i=0;i<n;i++){
            for(int j=0;j<n;j++){
                if(col[r][i]==j){//col[r][i]有保存的值,和j做比较
                    cout<<"Q   ";
                }else{
                    cout<<"X   ";
                }
            }
            cout<<endl<<endl;
        }
        cout<<"************当前页数"<<r+1<<"************"<<endl<<endl;
        cout<<"*********->查看下一个,<-查看上一个*********"<<endl;
    }
    int main(){
        cout<<"请输入皇后的数量:";
        cin>>n;
        if(n<3){
            cout<<"无解!"<<endl;
            return 0;
        }
        DFS(0);
        cout<<"一共有"<<tol<<"种布局"<<endl<<endl;
        int ch1=0;
        int ch2=0;
        int current = 0;
        show(current);
        //实现左右翻页
        while (1){   //无限循环
            //使用getch()读取方向键,读取方向键需要读取两次
              if (ch1=getch()){
                 ch2=getch();//第一次调用getch(),返回值224
                 switch (ch2){//第二次调用getch()
                 case 75: {  //←的ascll
                     if(current-1>=0){
                        current--;
                     }else{
                         current = tol-1;
                     }
                        system("cls
    ");
                        cout<<"请输入皇后的数量:"<<n<<endl;
                        cout<<"一共有"<<tol<<"种布局"<<endl<<endl;
                        show(current);
                    break;
                 }
                 case 77: {
                     if(current+1<=tol-1){
                        current++;
                     }else{
                         current = 0;
                     }
                        system("cls
    ");
                        cout<<"请输入皇后的数量:"<<n<<endl;
                        cout<<"一共有"<<tol<<"种布局"<<endl<<endl;
                        show(current);
    
                     break;
                 }
                 default:cout<<"输入错误!"<<endl;break;
    
                 }
              }
            }
           return 0;
    }

    代码说明:

    采用数组来存放结果,方向键的切换是采用读取getch来实现的。在函数check()中,判断冲突的条件是通过循环遍历来检验刚刚放进的第r行皇后是否与前r-1行放的发生冲突,即行数相等或列数相等。

    资料参考:

    n皇后详解及代码实现/C++ - Geek_Ling - 博客园 (cnblogs.com)

    https://www.cnblogs.com/yangxiao-/p/13683675.html

  • 相关阅读:
    PHP Fatal error: Uncaught Error: Call to undefined function pcntl_fork().. 开启php pcntl扩展实现多进程
    php实现共享内存进程通信函数之_shm
    Centos下10000次循环测试php对Redis和共享内存(shm)读写效率
    php操作共享内存shmop类及简单使用测试(代码)
    作为phper既然了解共享内存函数shmop的使用方法,那么就必须要了解一下信号量是什么,以及信号量使用的代码案例
    php简单使用shmop函数创建共享内存减少服务器负载
    作为php了解一下共享内存的概念及优缺点
    给PHP开启shmop扩展实现共享内存
    Centos环境自写脚本查看使用php或nginx占用内存
    linux下查看和添加path环境变量
  • 原文地址:https://www.cnblogs.com/1305536110-dym/p/14975305.html
Copyright © 2011-2022 走看看