巩固基础篇:八皇后问题:经典回溯法

#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月,可能存在一点历史遗留问题,欢迎指出)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值