N皇后非递归实现
马上上课了,以后有时间再细说。。。。。。
回溯:(偷个懒,从老师ppt上拷过来)
•状态树(解空间树)
–回溯法的求解过程实质上是一个先序遍历一颗状态树的过程,只是这棵状态树不是预先建立的,而是隐含在遍历过程中。
(可以通过画一个四皇后的解空间树来很嗨的理解,理解回溯的过程,图片有时间就更)
•约束函数
•节点与解
–完全解
–部分解,继续搜索
–死节点,回溯
#include<iostream>
#include<cmath>
#include<cstdio>
using namespace std;
int numsum=0;//记录摆法个数
bool check(int arr[],int k){//检查当前点是否合格
for(int i=1 ; i<k ; i++){
if(arr[i] == arr[k] || abs(arr[i]-arr[k]) == k-i)return false;
}
return true;
}
int print(int arr[],int n){//打印输出序列
for(int i=1;i<=n;i++){
cout<<arr[i]<<" ";
}
}
int main(){
int n;
cout<<"请输入皇后数量:";
cin>>n;//输入n皇后
int arr[100]={0};//a[1~n]存放可以取的值
int k=1;
while(k>=1){
while(arr[k]<n){
arr[k]++;
if(check(arr,k)&& k==n){//完全解
cout<<"第"<<++numsum<<"种"<<" ";
arr[0]++;
print(arr,n);
cout<<endl;
}
else if(check(arr,k)){//部分解
k++;
}
//既不是完全解,也不是部分解,就试探a[k]的其他取值,依次往后面遍历
}
//死结点,回溯
arr[k]=0;
k--;
}
cout<<"共有:"<<numsum<<"种摆法"<<endl;
return 0;
}
java版本
import java.util.Scanner;
public class Queue {
public static boolean check(int[] arr,int k){
for (int i = 1; i < k ; i++) {
if(arr[i] == arr[k] || Math.abs(arr[i]-arr[k]) == k-i){
return false ;
}
}
return true;
}
public static void print(int[] arr,int n){
for (int i = 1; i <= n; i++) {
System.out.print(arr[i] + " ");
}
System.out.println();
}
public static void main(String[] args) {
int[] arr = new int[100];
int n = 4;//棋子数量
int k = 1;
System.out.print("insert target num:");
n = new Scanner(System.in).nextInt();
while( k >= 1 ){
while( arr[k] < n ){
arr[k]++;
if( check(arr,k) && k == n){
System.out.println("第"+(++arr[0])+"种");
print(arr,n);
}
else if(check(arr,k)){
k++;
}
}
arr[k] = 0;
k--;
}
}
}