内容:
用回溯法求解N皇后问题。
要求:
(1)掌握回溯法通过搜索状态空间树中的每个问题状态来求解一个或全部可行解的算法思想;
(2)能够分析问题的具体特征并设计算法,运用回溯法的算法思想求解实际问题。
1.N皇后问题原始代码:
#include <iostream>
using namespace std;
extern int count1 = 0;
bool Place(int k, int i, int *x)
{
//判定两个皇后是否在同一列或在同一斜线上
for (int j = 0; j < k; j++)
if ((x[j] == i) || (abs(x[j] - i) == abs(j - k)))
return false;
return true;
}
//递归函数(求解n皇后问题)
void NQueens(int k, int n, int *x)
{
for (int i = 0; i < n; i++) //显式约束的第一种观点,x[k] = 0,1,···,n-1
{
if (Place(k, i, x)) //约束函数
{
x[k] = i;
if (k == n - 1)
{
for (i = 0; i < n; i++)
cout << x[i] << " "; //输出一个可行解
cout << endl;
count1++;
}
else
{
NQueens(k + 1, n, x); //深度优先进入下一层
}
}
}
}
void NQueens(int n, int *x)
{
NQueens(0, n, x);
}
int main()
{
int w;
while (1)
{
cin >> w;
count1 = 0;
int *queens = new int[w]; //w皇后
for (int i = 0; i < w; i++)
queens[i] = -1;
NQueens(w, queens);
cout << "The result is: " << count1 << endl;
}
return 0;
}
2.修改程序,使之在求得第一个可行解后算法终止
#include <iostream>
using namespace std;
extern int count1 = 0;
extern int flag = 0;
bool Place(int k, int i, int *x)
{
//判定两个皇后是否在同一列或在同一斜线上
for (int j = 0; j < k; j++)
if ((x[j] == i) || (abs(x[j] - i) == abs(j - k)))
return false;
return true;
}
//递归函数(求解n皇后问题)
void NQueens(int k, int n, int *x)
{
for (int i = 0; i < n; i++) //显式约束的第一种观点,x[k] = 0,1,···,n-1
{
if (Place(k, i, x)) //约束函数
{
x[k] = i;
if (k == n - 1)
{
for (i = 0; i < n; i++)
cout << x[i] << " "; //输出一个可行解
cout << endl;
flag = 1;
count1++;
}
else
{
NQueens(k + 1, n, x); //深度优先进入下一层
}
}
if (flag == 1)
{
break;
}
}
}
void NQueens(int n, int *x)
{
NQueens(0, n, x);
}
int main()
{
int w;
while (1)
{
cin >> w;
count1 = 0;
flag = 0;
cout << "The result is: " << endl;
int *queens = new int[w]; //w皇后
for (int i = 0; i < w; i++)
queens[i] = -1;
NQueens(w, queens);
}
return 0;
}