实验问题:
任何两个皇后放的位置不能在同一行、同一列、同一对角线。
每个皇后放在不同行上,一行放一个。
问题分析:
首先考虑第一个皇后的位置,将其放在第一行不同列上,考虑不同列的情况。确定第一个皇后,在依据条件确定第二个皇后,一直某个皇后的无法放在棋盘上(不满足条件),那么就回溯到不满足皇后的上一个皇后,再确定另一个合适的位置。不断循环。直到找到最后一个皇后合适的位置,即找到所有皇后合适的位置。
数学建模:
建立函数Queue(n)用于求8皇后问题;
建立函数place(k)用于判断放置的皇后条件限制;
当可以放置皇后时,置此处的状态数组tar[x][x[n]]为target;
当不满足放置条件时,其列数x[n]加1,再=在循环判断,直到n>9时,无法找出合适位置,回溯到上一个节点,并将此点所在行的状态数组置为0,表示下次还可以访问;
依次放置皇后直到放完8个皇后;
此问题循环式为Queue(n+1),递归出口为n==9
实验代码:
//使用回溯法递归皇后问题
#define _CRT_NO_SECURE_WARNINGS
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
using namespace std;
int x[9] = { 0 }; //记录皇后的列数
int target = -1;
int tar[9][9] = { 0 };
//判断某个位置是否可以放皇后
int place(int k) {
for (int i = 1;i <k;i++) {
if (x[k] == x[i] || abs(k - i) == abs(x[k] - x[i])) {
return 0;
}
}
return 1;
}
void print(int* a) {
for (int i = 1;i <= 8;i++) {
cout << "第" << i << "个皇后" << "放在第" << a[i] << "列" << endl;
}
cout << "*********************" << endl;
}
//放置皇后
void Queue(int n) {
x[n] = 1;
if (n == 9) {
print(x);
return;
}
//依列放入皇后
for (int i = 1;i <=8;i++) {
while ((!place(n)||tar[n][x[n]]==target)&&n<=9) {
x[n] = x[n] + 1;
if (x[n] >= 9) {
x[n] = 0;
x[n - 1] = 1;
for (int l = 1;l <= 8;l++) {
tar[n][l] = { 0 };
}
return;
}
}
tar[n][x[n]] = target;
Queue(n + 1);
}
}
int main() {
Queue(1);
system("pause");
return 0;
}
实验结果:
O(m*n*p) 其中n是每行尝试n次,循环尝试m次,检查p次