八皇后问题两种基本解法

八皇后1.0

形象,直接的思维。

//Queens.h

#pragma once
const int max_board = 30;
class Queens
{
public:
Queens(int size);
bool is_solved()const;
bool unguarded(int col)const;
void print()const;
void insert(int col);
void remove(int col);
int board_size;
private:
int count;
bool queen_square[max_board][max_board];//直接以二维数组模拟棋盘
};



Queens.cpp

#include"Queens.h"
#include<iostream>
using namespace std;


Queens::Queens(int size)
{
board_size = size;
count = 0;
for (int i = 0; i < size; i++)
{
for (int j = 0; j < size; j++)
queen_square[i][j] = false;//初始化,每个格子都还没放置皇后
}
}


bool Queens::is_solved()const
{
return (count == board_size);
}


bool Queens::unguarded(int col)const
{
int i;
bool ok = true;
for (i = 0; ok&&i < count; i++)
ok = !queen_square[i][col];
for (i = 1; ok&&count - i >= 0 && col - i >= 0; i++)
ok = !queen_square[count - i][col - i];
for (i = 1; ok&&col + i < board_size&&count - i >= 0; i++)//注意判断条件,而且只需判断上方的格子
ok = !queen_square[count - i][col + i];
return ok;
}


void Queens::print()const
{
for (int i = 0; i < board_size; i++)
{
for (int j = 0; j < board_size; j++)
{
if (queen_square[i][j])
cout << 1;
else
cout << 0;
cout << ' ';
}
cout << endl;
}
cout << endl << endl;
}


void Queens::insert(int col)
{
queen_square[count++][col] = true;//count++
}


void Queens::remove(int col)
{
queen_square[--count][col] = false;//--count
}


main.cpp


#include<iostream>
#include"Queens.h"
using namespace std;


void solve(Queens &Q)
{
if (Q.is_solved()) Q.print();
else
{
for (int col = 0; col < Q.board_size; col++)
{
if (Q.unguarded(col))
{
Q.insert(col);
solve(Q);
Q.remove(col);
}
}
}
}


void main()
{
int n;
cout << "How manu Queens?" << endl;
cin >> n;
Queens Q(n);
solve(Q);
system("pause");
}



八皇后2.0

提升效率,抽象化二维棋盘为一位数组;

//Queens.h

#pragma once
const int max_board = 30;
class Queens
{
public:
Queens::Queens(int size);
bool is_solved()const;
void print()const;
bool unguarded(int col)const;
void insert(int col);
void remove(int col);
int board_size;
private:
bool col_free[max_board];
bool upward_free[2 * max_board - 1];
bool downward_free[2 * max_board - 1];//check the unguarded places;
int count;
int queen_in_row[max_board];//excited,下标表示行,内容表示列,一位数组就可以表示皇后位置;
};


//Queens.cpp


#include"Queens.h"
#include<iostream>
using namespace std;


Queens::Queens(int size)
{
board_size = size;
count = 0;
for (int i = 0; i < size; i++)
{
col_free[i] = true;
}
for (int i = 0; i < (2 * size - 1); i++)
{
upward_free[i] = true;
downward_free[i] = true;
}
}


bool Queens::is_solved()const
{
return (count == board_size);
}


bool Queens::unguarded(int col)const
{
return (col_free[col] && upward_free[count + col]
&& downward_free[count - col + board_size - 1]);//refined a lot;
}


void Queens::print()const
{
for (int i = 0; i < board_size; i++)
{
for (int j = 0; j < board_size; j++)
{
if (queen_in_row[i] == j)//lightening!
cout << 1;
else
cout << 0;
cout << ' ';
}
cout << endl;
}
cout << endl << endl;
}


void Queens::insert(int col)
{
col_free[col] = false;
upward_free[count + col] = false;
downward_free[count - col + board_size - 1] = false;
queen_in_row[count++] = col;
}


void Queens::remove(int col)
{
--count;//新的insert()会覆盖原数组那个位置的元素,这个操作足够
col_free[col] = true;
upward_free[count + col] = true;
downward_free[count - col + board_size - 1] = true;
}


//main.cpp


#include"Queens.h"
#include<iostream>
using namespace std;


void solve(Queens &Q)//注意&符号该放的位置
{
if (Q.is_solved()) Q.print();
else
{
for (int col = 0; col < Q.board_size; col++)
{
if (Q.unguarded(col))
{
Q.insert(col);
solve(Q);
Q.remove(col);

/*回溯算法,remove()是为了找出全部解;不要错误理解成走进“死胡同”再出来试试其他路.

若进了“死胡同”,即继续下去无解,程序会自己默默结束,理解一下。*/
}
}
}
}


void main()
{
int n;
cout << "How many Queens?\n";
cin >> n;
Queens Q(n);
solve(Q);
system("pause");
}

你可能感兴趣的:(递归,八皇后,回溯)