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\n");
                    cout<<"请输入皇后的数量:"<<n<<endl;
                    cout<<"一共有"<<tol<<"种布局"<<endl<<endl;
                    show(current);
                break;
             }
             case 77: {
                 if(current+1<=tol-1){
                    current++;
                 }else{
                     current = 0;
                 }
                    system("cls\n");
                    cout<<"请输入皇后的数量:"<<n<<endl;
                    cout<<"一共有"<<tol<<"种布局"<<endl<<endl;
                    show(current);

                 break;
             }
             default:cout<<"输入错误!"<<endl;break;

             }
          }
        }
       return 0;
}

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


posted @ 2020-09-17 10:18  littlemelon  阅读(640)  评论(0编辑  收藏  举报