zoukankan      html  css  js  c++  java
  • C++程序算法题--N皇后

    题目

    N 皇后演示程序
    在N×N格的棋盘上放置彼此不受攻击的N 个皇后,按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子,求解可以放置的布局方式。
    设计要求:
    (1) 要求实现图形化棋盘显示;
    (2) 要求实现N 皇后布局演示,可以使用方向键进行布局切换。

    思路

    就是暴力搜索,一个位置一个位置的试。所以缺点显而易见,只能算<=10的情况,超过10就无法计算了。
    首先先简化问题,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子,设两个棋子的坐标分别为x1,y1,x2,y2.所以当|x1-x2|=|y1-y2|就冲突了。因为是一行一行的放,所以行冲突不用考虑,只需要考虑列冲突即y1!=y2。具体看代码和注释

    代码:

    #include<iostream>
    #include<conio.h>
    #include<stdlib.h>
    #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){
                    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){
              if (ch1=getch()){
                 ch2=getch();//第一次调用getch(),返回值224
                 switch (ch2){//第二次调用getch()
                 case 75: {
                     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;
    }
    

    运行结果:可以通过键盘方向键来进行布局的转换


  • 相关阅读:
    一个简单的反反爬~
    查缺补漏 -- python 之 and or的优先级
    从今天开始看《Redis深度历险》--HyperLogLog
    从今天开始看《Redis深度历险》--位图
    从今天开始看《Redis深度历险》--延时队列
    从今天开始看《Redis深度历险》--分布式锁
    redis之set【官方文档搬运+翻译】
    从今天开始看《Redis深度历险》--基础
    collections模块学习之namedtuple
    元组赋值谜题
  • 原文地址:https://www.cnblogs.com/yangxiao-/p/13683675.html
Copyright © 2011-2022 走看看