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

    初次接触递归的思想,折腾了一天多,本想自己把算法写出来的,但是最后还是看的书上的代码,发现原来这么简单,真是自惭形秽,下面是书上的代码

    #include <iostream>
    using namespace std;

    #define N 8

    bool matrix[N + 1][N + 1] = {0};

    bool IsLegal(bool matrix[N + 1][N + 1], const int &i, const int &j)
    {
    // 判断前面的i-1个棋子与matrix[i][j]是否冲突,i为1时合法

    for (int m = 1; m <= i - 1; ++m) {
    for (int n = 1; n <= N; ++n) { // 实际每一行只有一个棋子
    if (matrix[m][n] == 1) {
    if ( n == j || abs(i - m) == abs(j - n) ) // key, not bad
    return false;
    }
    }
    }
    return true;
    }

    void Print(bool matrix[N + 1][N + 1])
    {
    static int count = 1;
    printf("Case %d: ", count++);
    for (int i = 1; i <= N; i++) {
    for (int j = 1; j <= N; j++) {
    matrix[i][j] == 1 ? printf("%c ", 2) : printf(". ");
    }
    cout << endl;
    }
    cout << endl;
    }

    void Trial(const int i)
    { if (i > N) // 输出当前的合法布局
    Print(matrix);
    else
    for (int j = 1; j <= N; ++j)
    {
    matrix[i][j] = 1;
    if ( IsLegal(matrix, i, j) )
    Trial(i + 1);
    matrix[i][j] = 0; //如果一直成功的话,是执行不到这一行的
    }
    }

    int main(void)
    {
    Trial(1);

    return 0;
    }主要的重点在于Trial函数,对于第i行,先将第j个放入皇后,然后看下会不会冲突,没有冲突的话,进入第i+1行,直至第8行,如果一直成功,matrix[i][j] = 0是不会执行的,但是一旦有冲突if ( IsLegal(matrix, i, j) ) 为假时,那么不会执行下一步了,而是将第i行第j列的皇后拿走,再继续试下一列看能不能放皇后

     如何向上递归:比如当第4行所有的位子都冲突,即第4行都为0,因为第4行是嵌套在第3行中的,当i等于3时,matrix[i][j] = 1; if ( IsLegal(matrix, i, j) ) 这两步执行的没有问题,但是执行Trial(4);时不会继续递归,而是执行matrix[3][j] = 0;

    #include <iostream>
    using namespace std;
    #include<stdio.h>
    int IsAttact(int **p,int i,int j)
    {
    for(int i1=0;i1<i;i1++)
    {
    for(int j1=0;j1<8;j1++)
    {
    if(p[i1][j1]==0)
    {
    if(j==j1||abs(i1-i)==abs(j1-j))
    {return 0;}
    }
    }
    }
    return 1;
    }
    bool IsOK(int **p,int i)
    {
    int j = 0;
    bool foundSafePos = false;
    if(i==8)
    {foundSafePos=true;}
    else
    {
    while((!foundSafePos)&&(j<8))
    {
    if(IsAttact(p,i,j)==1)
    { //找到可以插入的位置
    p[i][j]=0;
    foundSafePos=IsOK(p,i+1);//到某一步执行不下去了,就会直接返回false而不会继续递归
    if(!foundSafePos)
    {
    p[i][j]=1;//第i+1步不行的话,就直接令第i行的当前列往下走一个
    j=j+1;
    }
    }
    else
    {
    j=j+1;
    }
    }
    }
    return foundSafePos;
    }
    void main()
    {
    int **p=new int *[8];
    for(int i1=0;i1<8;i1++)
    {
    p[i1] = new int[8];
    }
    for(int i2=0;i2<8;i2++)
    {
    for(int j2=0;j2<8;j2++)
    {
    p[i2][j2]=1;
    }
    }
    bool IsSucceed=IsOK(p,0);
    if(IsSucceed)
    {
    for(int i2=0;i2<8;i2++)
    {
    printf("%d %d %d %d %d %d %d %d ",p[i2][0],p[i2][1],p[i2][2],p[i2][3],p[i2][4],p[i2][5],p[i2][6],p[i2][7]);
    }
    }
    }

    基本原理一样,因为是一开始自己写的,就想找出问题,并写完它。

  • 相关阅读:
    bzoj3033: 太鼓达人
    CH Round #24
    王志明:编辑部不送审,把你的投稿直接拒掉了,怎么办?
    用TinyXml做XML解析示例 TinyXml查找唯一节点及修改节点操作
    QT XML文档的解析 QXmlStreamReader, DOM,SAX 三种解析方法 简单示例
    QT 使用QUdpSocket QUdpServer UDP 建立客户端与服务器端
    QT 使用QTcpServer QTcpSocket 建立TCP服务器端 和 客户端
    Qt QThread 线程创建,线程同步,线程通信 实例
    Qt QT的IO流 QT输入输出
    Qt QSortFilterProxyModel示例代码, 使用方法
  • 原文地址:https://www.cnblogs.com/yunerlalala/p/5471412.html
Copyright © 2011-2022 走看看