当前位置:   article > 正文

n皇后问题(全排列的延伸)_【基础】n皇后问题

【基础】n皇后问题

问题 D: 【递归入门】n皇后 问题(原始的8皇后问题)

时间限制: 1 Sec  内存限制: 128 MB
提交: 588  解决: 281
[提交][状态][讨论版][命题人:外部导入]

题目描述

       会下国际象棋的人都很清楚:皇后可以在横、竖、斜线上不限步数地吃掉其他棋子。如何将8个皇后放在棋盘上(有8 * 8个方格),使它们谁也不能被吃掉!这就是著名的八皇后问题。 

 

输入

一个整数n( 1 < = n < = 10 ) 

输出

每行输出对应一种方案,按字典序输出所有方案。每种方案顺序输出皇后所在的列号,相邻两数之间用空格隔开。如果一组可行方案都没有,输出“no solute!”

样例输入

4

样例输出

2 4 1 3
3 1 4 2

 C++实现版本:

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cmath>
  4. #include<string>
  5. #include<vector>
  6. #include<algorithm>
  7. using namespace std;
  8. const int maxn=10010;
  9. int n,a[maxn];
  10. int main(){
  11. int n,cnt=0;
  12. cin>>n;
  13. for(int i=1;i<=n;i++)
  14. a[i]=i;
  15. do{
  16. int flag=1;
  17. for(int i=1;i<=n;i++){
  18. for(int j=i+1;j<=n;j++){
  19. if(abs(i-j)==abs(a[i]-a[j]))
  20. flag=0;
  21. }
  22. }
  23. if(flag){
  24. cnt=1;
  25. for(int i=1;i<=n;i++)
  26. cout<<a[i]<<" ";
  27. cout<<endl;
  28. }
  29. }while(next_permutation(a+1,a+n+1));
  30. if(cnt==0) cout<<"no solute!"<<endl;
  31. return 0;
  32. }

递归版:

   快被坑死了,刚开始散列数组设定的hash,提交的时候一直编译错误,然后也找不到问题的所在,后来改成hashTable对了。。

才知道hash 也是c++的一个库函数。。。。。。。。 

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cmath>
  4. #include<string>
  5. #include<vector>
  6. #include<algorithm>
  7. using namespace std;
  8. const int maxn=10010;
  9. int n,P[maxn],cnt=0;
  10. bool hashTable[maxn]={false};
  11. void generateP(int idx){//全排列就相当于往一个数组里不断的填数
  12. if(idx==n+1){//当产生一个排列后 判断是不是满足条件的排列
  13. int flag=1;
  14. for(int i=1;i<=n;i++){
  15. for(int j=i+1;j<=n;j++){
  16. if(abs(i-j)==abs(P[i]-P[j]))//如果在同一条斜线上
  17. flag=0;
  18. }
  19. }
  20. if(flag){
  21. cnt=1;
  22. for(int i=1;i<=n;i++)
  23. cout<<P[i]<<" ";
  24. cout<<endl;
  25. }
  26. return ;
  27. }
  28. for(int i=1;i<=n;i++){
  29. if(hashTable[i]==false){
  30. hashTable[i]=true;
  31. P[idx]=i;
  32. generateP(idx+1);
  33. hashTable[i]=false;
  34. }
  35. }
  36. }
  37. int main(){
  38. cin>>n;
  39. generateP(1);//1下标开始产生排列
  40. if(cnt==0) cout<<"no solute!"<<endl;
  41. return 0;
  42. }

  剪枝版:

  1. void generateP(int idx){//全排列就相当于往一个数组里不断的填数
  2. if(idx==n+1){//
  3. cnt=1;
  4. for(int i=1;i<=n;i++)
  5. cout<<P[i]<<" ";
  6. cout<<endl;
  7. return ;
  8. }
  9. for(int i=1;i<=n;i++){
  10. if(hashTable[i]==false){
  11. int flag=1;//在选择皇后的位置的时候就判断这个位置和已经放皇后的位置是否位于同一条斜线
  12. for(int pre=1;pre<idx;pre++){
  13. if(abs(pre-idx)==abs(P[pre]-i)){
  14. flag=0;
  15. break;
  16. }
  17. }
  18. if(flag==0) continue;//若位于同一条斜线则表明该种情况以后的各个分问题都不需要再考虑
  19. hashTable[i]=true;
  20. P[idx]=i;
  21. generateP(idx+1);//处理下一个位置
  22. hashTable[i]=false;//当递归返回至此,表明idx下标为i 的子问题处理完毕,还原
  23. }
  24. }
  25. }

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/神奇cpp/article/detail/825512
推荐阅读
相关标签
  

闽ICP备14008679号