n皇后问题

N皇后问题(n > 3):

简述:这道题用到了回溯法,熟悉下递归回溯

解决难点:

1) 由于使用的是一维数组表示地图信息,所以用到了x = index % width 、y = index / width

2) 在回溯过程中,保证回来的时候,地图信息要保留原先的状况,这里我用了两个数组saveLegal[] 和saveMap[]记录了加入n -1个皇后前的地图信息,在函数从n - 1个皇后回溯到n时可以还原legal[] 和 map[]数组的状态,这步骤很重要!

3)还有就是判断皇后之间是否冲突,这个用legal[]数组标记不可摆放位置,那么放下一个皇后的时候就别放在这些legal[]为false的点上

代码:

/***********************N_Queen问题*************************/
#include <iostream>
#include <math.h>
#include <stdlib.h>

using namespace std;

static bool *legal; //记录不可摆放位置
static bool *map;  //记录摆放皇后的位置
static int width; //地图初始的宽度,就是皇后的数目


void Intialize(int n){
	width = n;
	legal = new bool[width * width];
	for(int i = 0;i < width * width;i++){
		legal[i] = true;
	}
	map = new bool[width * width];
	for(int i = 0;i < width * width;i++){
		map[i] = false;
	}
}


//这里x、y的坐标以是到(0,0)的距离
int GetX(int num,int width){
	return num % width;
}

int GetY(int num,int width){
	return num / width;
}

//从在n行,i列放下某个皇后之后,需要把后面n-1个皇后不能放的位置标记出来
void setFalse(int n,int i){
	    int index = n * width + i;
		//横向置为false
		for(int j = 0;j < width;j++){
				legal[n * width + j] = false;
		}
		//纵向置为false
		for(int j = 0;j < width;j++){
				legal[j * width + i] = false;
		}
		//45度斜线置为false
		for(int j = 0;j < width * width;j++){
			if((GetX(j,width) + GetY(j,width)) == (GetX(index,width) + GetY(index,width))){
				legal[j] = false;
			}
		}
		//135度斜线置为false
		for(int j = 0;j < width * width;j++){
			if((GetX(j,width) - GetY(j,width)) == (GetX(index,width) - GetY(index,width)))
					legal[j] = false;
		}
}

//具体摆放的代码,从第N个皇后进行摆放到1结束
static int cnt = 1; //记录第几组结果
void LayQueen(int n){
	if(n == 0){
		cout <<"第" << cnt++ << "组:" << endl;
		for(int i = 0;i < width * width;i++){
			if(map[i]){
				int height = i / width;
				cout << "(" << (i % width) << "," << height << ") ";
			}
		}
		cout << "\nMap: " << endl;
		for(int i = 0;i < width * width;i++){
			if(map[i])
				cout << "1 ";
			else
				cout << "0 ";
			if(i % width == width - 1)
				cout << endl;
		}
		cout << "\n\n";
	}else{
		for(int i = 0;i < width;i++){
			//第n个放在n-1行,每个位置都试过去,得到所有情况
			if(legal[(n - 1) * width + i]){
				/*
				 * *********用来存放放置n - 1个皇后前的状态****************/
				bool *saveLegal = new bool[width * width];
				for(int j = 0;j < width * width;j++){
					saveLegal[j] = legal[j];
				}
				bool *saveMap = new bool[width * width];
				for(int j = 0;j < width * width;j++)
					saveMap[j] = map[j];
				/********************************************
				 * */
				//修改可放置皇后位置后,设置不合法位置setFalse放入下一个皇后
				map[(n - 1) * width + i] = true; //放下(i,n-1)皇后
				setFalse(n - 1,i); // 第一行是0行 所以带入n - 1行, i列 皇后位置为(n-1,i)
				LayQueen(n - 1);
				//
				/*
				 * *************还原放置n - 1个皇后前的状态****************/
				for(int j = 0;j < width * width;j++)
					legal[j] = saveLegal[j];
				for(int j = 0;j < width * width;j++)
					map[j] = saveMap[j];
				delete []saveLegal;
				delete []saveMap;
			    /********************************************
			     * */
			}
		}
	}
}


int main(){
	int NumOfQueen = 8;
	Intialize(NumOfQueen);
	LayQueen(NumOfQueen);
	return 0;
}

输出(只截取了部分):

n皇后问题_第1张图片


你可能感兴趣的:(delete)