#include<iostream>
#include<string.h>
#include<stdio.h>
#include<windows.h>
#include<time.h>
#include<iomanip>
#include<stdlib.h>
#include<time.h>
using namespace std;
typedef long long ll;
const int I = 200001;
int row[8], col[8];
int map[8][8];
int vis[10];
int coo = 0;
//经典回溯法回顾
bool inplace(int count) {
int r = count / 8;
int c = count % 8;
if (row[r])return false;
if (col[c])return false;
for (int i = 1; i<8; i++) {//判断所在斜线上是否已经有皇后,如果有就返回false
if (map[r - i][c + i] && r - i >= 0 && c + i<8)return false;
if (map[r + i][c - i] && r + i<8 && c - i >= 0)return false;
if (map[r - i][c - i] && r - i >= 0 && c - i >= 0)return false;
if (map[r + i][c + i] && r + i<8 && c + i<8)return false;
}
return true;
}
void backtrack(int count) {
HANDLE h;
h = GetStdHandle(STD_OUTPUT_HANDLE);
srand((int)time(0));
if (count == 64) {
coo++;
cout << coo << endl;
for (int i = 0; i<8; i++)
{
for (int j = 0; j<8; j++) {
if (map[i][j]) {
int t = rand()%3+11;//这里可以自己调一下颜色范围,直接给t赋值也可以
SetConsoleTextAttribute(h, t);
cout << setw(3) << "☆" << " ";
SetConsoleTextAttribute(h, 10);
}
else { cout << setw(3) << "○" << " "; }
}
cout << endl << endl;
}
cout << endl << endl;
//Sleep(250);//可以设置输出的时间间隔(ms)
//getchar();//或者按回车键再次输出,方便浏览
return;//每次64个位置填完后就输出,然后返回,重新开始
}
int r = count / 8;
int c = count % 8;
if (row[r] == 0) { //这一行还没放一个皇后
for (int i = 0; i<8; i++) { //从0到7中选一个数
if (inplace(count + i) && c + i<8)
{
row[r] = 1;//符合要求后这一行进行标记为1
col[c + i] = 1;
map[r][c + i] = 1;
backtrack(r * 8 + 8);// 开始从下一行开始回溯,
//↑上面这一步执行完毕后一整个图就出来了(即会直接走到尽头再执行下一步)
col[c + i] = 0; // 去标记,进行下一次八皇后位置的重新筛选
map[r][c + i] = 0;
row[r] = 0;
}
}
}
else { backtrack(r * 8 + 8); }//执行这一步说明上面的放法不行,重新从那一步开始
}
int main() {
for (int i = 0; i<8; i++) {
//每次都初始化
memset(map, 0, sizeof(map));
memset(row, 0, sizeof(row));
memset(col, 0, sizeof(col));
map[0][i] = 1;//初始位置标记为1
row[0] = 1;
col[i] = 1;
backtrack(0);
}
system("pause");
}
输出一共有92种情况,如下所示(截取最后两种):
可能会遇到win32窗口显示不出完整92种的情况,此时只需要调整一下窗口的缓冲区就可以了,
右键窗口边框→属性→窗口缓冲区高度选项→尽量调大,2000-3000就可以了:如下
(本代码写于2016年2月,可能存在一点历史遗留问题,欢迎指出)