⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 八皇后(改进)(函数回溯).cpp

📁 自己收集的八皇后问题相关知识,有不少源代码,能解决八皇后问题
💻 CPP
字号:

//////////////////////////////////////////////////////
//采用回溯法求解n皇后问题
//用函数进行回溯
//
//经过适当的优化后可以算到32
//
//完成于2007.7.15
//张锦
///////////////////////////////////////////////////////
#include <iostream>

#include <vector>

#include <algorithm>

#include <math.h>
#include <windows.h>
using namespace std;

typedef vector<int> stack;

int backnum = 0;

void PrintMatrix(int **matrix,int n)
{
	int i = 0,j = 0;
	for(i = 0; i < n; i++)
	{
		for(j = 0; j < n; j++)
		{
			if(matrix[i][j] == 1)
			{
				cout<<"*"<<' ';
			}
			else if(matrix[i][j] == 0)
			{
				cout<<"#"<<' ';
			}
			else
			{
				cout<<'a'<<' ';
			}
		}
		cout<<endl;
	}

}

bool CheckMatrix(int **matrix,int i,int j,int n)
{
	int able = 0;
	int lie = 0;
	matrix[i][j] = 1;
	//做合法性检查
	//不在同一列
	for(lie = i; lie >= 0; lie--)
	{
		if(matrix[lie][j] == 1)
		{
			able++;
		}
	}
	//不在正对角线上
	int num = 0;
	if(i > j)
	{
		num = j;
	}
	else
	{
		num = i;
	}

	for(lie = 0;lie <= num; lie++)
	{
		if(matrix[i-lie][j-lie] == 1)
		{
			able++;
		}
	}
	//不在反对角线上
	if(i > n-1-j)
	{
		num = n-1-j;
	}
	else
	{
		num = i;
	}
	for(lie = 0;lie <= num; lie++)
	{
		if(matrix[i-lie][j+lie] == 1)
		{
			able++;
		}
	}
	if(able == 3)
	{
		return true;
	}
	else
	{
		matrix[i][j] = 0;
		return false;
	}

}

int ChangeMatrix(int **matrix,int i,int j,int n,int value)
{
	int able = 0;
	int lie = 0;
	int origin = matrix[i][j];
	//做合法性检查
	//同一列
	int Change = 0;
	for(lie = i; lie < n; lie++)
	{
		if(matrix[lie][j] != value)
		{
			matrix[lie][j] = value;
			Change++;
		}
	}
	//正对角线上
	int num = 0;
	if(i > j)
	{
		num = n-1-i;
	}
	else
	{
		num = n-1-j;
	}

	for(lie = 0;lie <= num; lie++)
	{
		if(matrix[i+lie][j+lie] != value)
		{
			matrix[i+lie][j+lie] = value;
			Change++;
		}
		
	}
	//反对角线上
	if(j > n-1-i)
	{
		num = n-1-i;
	}
	else
	{
		num = j;
	}
	for(lie = 0;lie <= num; lie++)
	{
		if(matrix[i+lie][j-lie] != value)
		{
			matrix[i+lie][j-lie] = value;
			Change++;
		}
	
	}
	
	matrix[i][j] = origin;
	return Change;
}

void ChangeMatrix(int **matrix,int n)
{
	int i = 0,j = 0;
	for(i = 0;i < n; i++)
	{
		for(j = 0;j < n; j++)
		{
			if(matrix[i][j] == 2)
			{
				matrix[i][j] = 0;
			}
		}
	}
	for(i = 0;i < n; i++)
	{
		for(j = 0;j < n; j++)
		{
			if(matrix[i][j] == 1)
			{
				ChangeMatrix(matrix,i,j,n,2);
			}
		}
	}

}



void Queen(int **matrix,int i,int j,int n)
{
	backnum++;
	int able = 0;
	int lie = 0,hang = 0;
	int pos = 0;
	if(i == 0 && j == 0)
	{
		matrix[i][j] = 1;
		//ChangeMatrix(matrix,n);
		ChangeMatrix(matrix,i,j,n,2);
		Queen(matrix,i+1,2,n);//下一行
		return;
	}
	else if(j > n -1) //一行找到头了,回退
	{
		/*
		cout<<"i = "<<i<<endl;
		cout<<"j = "<<j<<endl;
		cout<<"backnum = "<<backnum<<endl;
		PrintMatrix(matrix,n);
		//*/
		///*
		
		int num = 0;
		for(lie = 0; lie < n; lie++)
		{
			if(matrix[i-1][lie] == 1)
			{
				matrix[i-1][lie] = 0;
				pos = lie;
			//	break;
			}
		}
		/*
		for(lie = 0; lie < n; lie++)
		{
			num += matrix[i][lie];
		}
		if(num == 2*(n-1))
		{
			cin>>lie;
			Queen(matrix,i,0,n);ChangeMatrix(matrix,n);//不回退从这一行的起始位置开始
			return;
		}
		//*/
		//*/
		//ChangeMatrix(matrix,i-1,pos,n,0);
		//matrix[i-1][pos] = 0;
		ChangeMatrix(matrix,n);
		
	
		Queen(matrix,i-1,pos+1,n);//从上一行的下一个位置开始
		return;
	}
	else if(i == n-1 && j > n -1)
	{
		cout<<"无解------"<<endl;
		return;
	}
	else 
	{
		if(matrix[i][j] == 0 &&CheckMatrix(matrix,i,j,n))//可以放做下一行
		//if(CheckMatrix(matrix,i,j,n))
		{
			//ChangeMatrix(matrix,i,j,n,2);
			ChangeMatrix(matrix,n);
			/*
			cout<<"i = "<<i<<endl;
			cout<<"j = "<<j<<endl;
			cout<<"backnum = "<<backnum<<endl;
			PrintMatrix(matrix,n);
			//*/
			if(i == n-1)
			{
				cout<<"找到解了--------"<<endl;
				PrintMatrix(matrix,n);
				return;
			}
			else
			{
				for(lie = 0;lie < n; lie++)
				{
					if(matrix[i+1][lie]==0)
						break;
				}
				Queen(matrix,i+1,lie,n);
				/*
				
				if(j+2 < n&& i < n)
				{

					if(j+2>lie)
					{
					Queen(matrix,i+1,j+2,n);
					}
					else
					{
						Queen(matrix,i+1,lie,n);
					}
				}
				else
				//*/
				{
					//Queen(matrix,i+1,0,n);
				}
				return;
			}
		}
		else//不可以做,做这一行的下一个元素
		{
			Queen(matrix,i,j+1,n);
			
			return;
		}
		
	}

}

int first = 0;
int next = 0;
int Select(int **matrix,int i,int n)
{
	int lie = 0;
	int num = n;
	int CM = 0;
	//找出改变次数最少的那个值
	for(int j = 0;j < n; j++)
	{
		if(matrix[i][j]==0)
		{
			CM = ChangeMatrix(matrix,i,j,n,2);
			if(num > CM)
			{
				num = CM;
				lie = j;
			}
			ChangeMatrix(matrix,n);
		}
	}
	return lie;
}
void Queen1(int **matrix,int i,int j,int n)
{
	backnum++;
	int able = 0;
	int lie = 0,hang = 0;
	int pos = 0;
	if(i == 0 && j == 0)
	{
		matrix[i][j] = 1;
		//ChangeMatrix(matrix,n);
		ChangeMatrix(matrix,i,j,n,2);
		Queen1(matrix,i+1,2,n);//下一行
		return;
	}
	else if(j > n -1) //一行找到头了,回退
	{
		/*
		cout<<"i = "<<i<<endl;
		cout<<"j = "<<j<<endl;
		cout<<"backnum = "<<backnum<<endl;
		PrintMatrix(matrix,n);
		//*/
		///*
		
		int num = 0;
		for(lie = 0; lie < n; lie++)
		{
			if(matrix[i-1][lie] == 1)
			{
				matrix[i-1][lie] = 0;
				pos = lie;
			//	break;
			}
		}
		/*
		for(lie = 0; lie < n; lie++)
		{
			num += matrix[i][lie];
		}
		if(num == 2*(n-1))
		{
			cin>>lie;
			Queen(matrix,i,0,n);ChangeMatrix(matrix,n);//不回退从这一行的起始位置开始
			return;
		}
		//*/
		//*/
		//ChangeMatrix(matrix,i-1,pos,n,0);
		//matrix[i-1][pos] = 0;
		ChangeMatrix(matrix,n);
		
	
		Queen1(matrix,i-1,pos+1,n);//从上一行的下一个位置开始
		return;
	}
	else if(i == n-1 && j > n -1)
	{
		cout<<"无解------"<<endl;
		return;
	}
	else 
	{
		if(matrix[i][j] == 0 &&CheckMatrix(matrix,i,j,n))//可以放做下一行
		//if(CheckMatrix(matrix,i,j,n))
		{
			//ChangeMatrix(matrix,i,j,n,2);
			ChangeMatrix(matrix,n);
			/*
			cin>>first;
			cout<<"i = "<<i<<endl;
			cout<<"j = "<<j<<endl;
			cout<<"backnum = "<<backnum<<endl;
			PrintMatrix(matrix,n);
			//*/
			if(i == n-1)
			{
				cout<<"找到解了--------"<<endl;
				PrintMatrix(matrix,n);
				return;
			}
			else
			{
				int sum = 0;
				for(hang = i+1; hang < n; hang++)
				{
					sum = 0;
					for(lie = 0; lie < n; lie++)
					{
						sum+=matrix[hang][lie];
					}
					if(n*2 == sum)
					{
						for(lie = j+1;lie < n; lie++)
						{
							if(matrix[i][lie]==0)
							break;
						}
						matrix[i][j] = 0;
						ChangeMatrix(matrix,n);
						Queen1(matrix,i,lie,n);
						return;
					}
				}
				//////////////////////////////////
				//可以算到32
				///*
				if(i < n/2-1)
				{
				//*	
				if(j == 0)
					{
						Queen1(matrix,i+1,j,n);
					}
					else if(j+2 < n)
					{
						Queen1(matrix,i+1,j+2,n);
					}
					else
					{
						//Queen1(matrix,i+1,0,n);
						Queen1(matrix,i+1,(j+2)%n,n);
						//Queen1(matrix,i+1,(j+2)%(n-1),n);
					}
					//*/
					return;
				}
				else
				{
					lie = Select(matrix,i+1,n);
					Queen1(matrix,i+1,lie,n);
					return;
				}
				return;
			}
		}
		else//不可以做,做这一行的下一个元素
		{
			for(lie = j+1;lie < n; lie++)
				{
					if(matrix[i][lie]==0)
						break;
				}
			Queen1(matrix,i,lie,n);
			
			return;
		}
		
	}

}

void main()

{
	cout<<"八皇后问题:"<<endl;
	int n = 0;
	do
	{
	cout << "请输入皇后的个数:" ;
	cin >> n;
	int **matrix;
	matrix = new int*[n];
	int i = 0 , j = 0;
	for(i = 0; i < n; i++)
	{
		matrix[i] = new int[n];
		for(j = 0; j < n; j++)
		{
			matrix[i][j] = 0;
		}
		
	}
	//PrintMatrix(matrix,n);
	//*
	first = n/2;
	next = n/2;
	if(n%2 == 0)
	{
		Queen1(matrix,0,n/2,n);
	}
	else
	{
		Queen1(matrix,0,n/2,n);
	}
	//*/
	for(i = 0; i < n; i++)
	{
		for(j = 0; j < n; j++)
		{
			if(matrix[i][j] == 1)
			{
				cout<<j<<' ';
			}
		}
	}
	cout<<endl;
	cout<<"backnum = "<<backnum<<endl;
	backnum = 0;
	}while(n >= 4);
	
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -