在电脑上突然发现了以前的作业,在这里保存一下。
是C++程序。
是C++程序。
////////////////////////////////////////////////////////////////////////////////////////////////////
//作业:5-4, 八皇后问题求解。
//说明: 问题抽象成输出8个数字(0-----7) 分别表示第i 行上皇后的位置,
// 例: 输出7 1 3 0 6 4 2 5 表示这个合法布局是在第一行第8 个位
// 置放置第一个皇后,第二行第2 个位置放置第二个皇后.
// 最后输出的5 表示在第八行第6 个位置放置第八个皇后。
//注意: 本题记数方式是从0 到7 ,即在本题中0 表示第一行,1 表示第
// 二行,i 表示第i-1 行。
//问题抽象: 此问题被我抽象输出0---7 八个数字,满足以下条件:
// 一,不重复输出,即已经输出过的数字,不能再输出。
// 二,当要输出第n 个数字时,(此时已经有位置的前n-1 个数
// 字被保存到数组a[] 中),假设这个数字是i 则应满足:
// (a[k]-(n-k))==i&&(a[k]+(n-k))==i (k是数组中已经存放的第几个数)
// 这是对题中要求的任意两个不在同一对角线上的抽象
// 这两个条件的满足是在Find() 函数实现的。
//时间:2002年11月29日。
//作者: 暴风雨
//欢迎交流
////////////////////////////////////////////////////////////////////////////////////////////////////
#include<iostream>
using namespace std;
//定义全局变量sum 作计数器来统计合法的布局。
int sum=0;
//Find()函数,需要三个变量:
// 一,数组a[] 存放当前已经有合法位置的皇后位置。
// 二,当前要找到的第n 个皇后的合法位置。
// 三,整数i 表示当前要将皇后放置的位置,Find()函数正是要
// 检测这个位置的合法性。如果不合法返回true,合法返回
// false.
bool Find(int a[],int n,int i){
for(int k=0;k<n;k++){ //if 语句的三个判断的意义是
if(a[k]==i||(a[k]-(n-k))==i||(a[k]+(n-k))==i){ //分别检测当前位置和
return true; //已经布置好的第k 个位置是否
} //冲突,和第k 个位置的正反对
} //角线是否 冲突。
return false;
}
//递归算法求解八皇后的位置函数Bahuanghou()。
//此函数需要两个参数:
// 一,数组a[] 存放当前已经有合法位置的皇后位置。
// 二,当前要找到的第n 个皇后的合法位置。
void Bahuanghou(int a[],int n){
//每次进入循环要从0---7 检测位置的合法性。
for(int i=0;i<8;i++){
if(Find(a,n,i)){ //如果Find() 函数为true ,说明位置不和法。
if(i==7){ //这是如果已经找到了该行的最后一个元素
return; //则函数不必继续执行,返回上一级递归。
}
else //如果当前位置没有到最后一个
continue; //则继续向下循环以找到合法位置
}
a[n++]=i; //则将这个位置存放到a[]中,并使个数n++.
if(n==8){ //如果当前n =8 则说明找到了一组合法的布局。
cout<<"第"<< ++sum<<"组"<<"\t"; //sum计数器记录这组的存在。
for(int k=0;k<8;k++) //输出这组合法布局。
cout<<a[k]<<" ";
cout<<endl; //输出换行,以便下一组在下一行输出。
return; //返回上一级递归。
} //如果n!=8 继续递归,以寻找下一个合法位置。
Bahuanghou(a, n); //非常重要的一步,每次递归返回时都要将前
a[--n]=-1; //一个合法a[n-1] 删除,因为当递归结束时,
} //的位置都不和法,在这些情况下都要,更新
} //前一个和法位置。
//主函数。
int main(){
int a[8]; //定义存放位置的数组a[].
for(int k=0;k<8;k++) //将数组中的值初始化为-1,表示没有合法位置
a[k]=-1; //存入。
int n=0; //定义n记录当前找到合法位置的个数。
Bahuanghou(a,n); //递归查找合法的八皇后位置。
cout<<"合法的位置共"<<sum<<"组"; //输出合法位置总数。
return 0;
}
//作业:5-4, 八皇后问题求解。
//说明: 问题抽象成输出8个数字(0-----7) 分别表示第i 行上皇后的位置,
// 例: 输出7 1 3 0 6 4 2 5 表示这个合法布局是在第一行第8 个位
// 置放置第一个皇后,第二行第2 个位置放置第二个皇后.
// 最后输出的5 表示在第八行第6 个位置放置第八个皇后。
//注意: 本题记数方式是从0 到7 ,即在本题中0 表示第一行,1 表示第
// 二行,i 表示第i-1 行。
//问题抽象: 此问题被我抽象输出0---7 八个数字,满足以下条件:
// 一,不重复输出,即已经输出过的数字,不能再输出。
// 二,当要输出第n 个数字时,(此时已经有位置的前n-1 个数
// 字被保存到数组a[] 中),假设这个数字是i 则应满足:
// (a[k]-(n-k))==i&&(a[k]+(n-k))==i (k是数组中已经存放的第几个数)
// 这是对题中要求的任意两个不在同一对角线上的抽象
// 这两个条件的满足是在Find() 函数实现的。
//时间:2002年11月29日。
//作者: 暴风雨
//欢迎交流
////////////////////////////////////////////////////////////////////////////////////////////////////
#include<iostream>
using namespace std;
//定义全局变量sum 作计数器来统计合法的布局。
int sum=0;
//Find()函数,需要三个变量:
// 一,数组a[] 存放当前已经有合法位置的皇后位置。
// 二,当前要找到的第n 个皇后的合法位置。
// 三,整数i 表示当前要将皇后放置的位置,Find()函数正是要
// 检测这个位置的合法性。如果不合法返回true,合法返回
// false.
bool Find(int a[],int n,int i){
for(int k=0;k<n;k++){ //if 语句的三个判断的意义是
if(a[k]==i||(a[k]-(n-k))==i||(a[k]+(n-k))==i){ //分别检测当前位置和
return true; //已经布置好的第k 个位置是否
} //冲突,和第k 个位置的正反对
} //角线是否 冲突。
return false;
}
//递归算法求解八皇后的位置函数Bahuanghou()。
//此函数需要两个参数:
// 一,数组a[] 存放当前已经有合法位置的皇后位置。
// 二,当前要找到的第n 个皇后的合法位置。
void Bahuanghou(int a[],int n){
//每次进入循环要从0---7 检测位置的合法性。
for(int i=0;i<8;i++){
if(Find(a,n,i)){ //如果Find() 函数为true ,说明位置不和法。
if(i==7){ //这是如果已经找到了该行的最后一个元素
return; //则函数不必继续执行,返回上一级递归。
}
else //如果当前位置没有到最后一个
continue; //则继续向下循环以找到合法位置
}
a[n++]=i; //则将这个位置存放到a[]中,并使个数n++.
if(n==8){ //如果当前n =8 则说明找到了一组合法的布局。
cout<<"第"<< ++sum<<"组"<<"\t"; //sum计数器记录这组的存在。
for(int k=0;k<8;k++) //输出这组合法布局。
cout<<a[k]<<" ";
cout<<endl; //输出换行,以便下一组在下一行输出。
return; //返回上一级递归。
} //如果n!=8 继续递归,以寻找下一个合法位置。
Bahuanghou(a, n); //非常重要的一步,每次递归返回时都要将前
a[--n]=-1; //一个合法a[n-1] 删除,因为当递归结束时,
} //的位置都不和法,在这些情况下都要,更新
} //前一个和法位置。
//主函数。
int main(){
int a[8]; //定义存放位置的数组a[].
for(int k=0;k<8;k++) //将数组中的值初始化为-1,表示没有合法位置
a[k]=-1; //存入。
int n=0; //定义n记录当前找到合法位置的个数。
Bahuanghou(a,n); //递归查找合法的八皇后位置。
cout<<"合法的位置共"<<sum<<"组"; //输出合法位置总数。
return 0;
}