用栈+回溯+非递归解决N皇后问题
2016-04-05 18:19
330 查看
问题及代码:
运行结果:
思路:
queen[row]数组记录第row行上皇后的列位置;
st栈记录当前行数;
从第0行开始,依次试探0-n-1列;
当row==n-1说明全部成功放置皇后;
当queen[row]>=n说明当前行下,各列试探完毕,都不能成功放置,所以要回溯到上一行,将当前行出栈。
/* * Copyright (c) 2016, 烟台大学计算机与控制工程学院 * All rights reserved. * 文件名称:queen.cpp * 作 者:单昕昕 * 完成日期:2016年4月4日 * 版 本 号:v1.0 */ #include <iostream> #include <malloc.h> #include <cstdio> #include <cmath> using namespace std; const int MaxSize=400; typedef struct linknode//顺序栈 { int data[MaxSize]; int top; } SqStack; SqStack *st; void initStack(SqStack *&s)//初始化 { s=(SqStack *)malloc(sizeof(SqStack)); s->top=-1; } bool Push(SqStack *&s,int e)//压入栈 { if(s->top==MaxSize-1) return false; s->top++; s->data[s->top]=e; return true; } bool Pop(SqStack *&s)//移除栈顶元素 { if(s->top==-1) return false; s->top--; return true; } bool GetTop(SqStack *s,int &e)//取栈顶元素 { if(s->top==-1) return false; e=s->data[s->top]; return true; } bool StackEmpty(SqStack *s)//判断栈是否为空 { return(s->top==-1); } void DestroyStack(SqStack *&s)//销毁栈 { free(s); } bool Check(int *qu, int t)//能放返回真,否则为假 { int i; for(i=0; i<t; i++)//逐行判断 if(qu[i]==qu[t]||abs(t-i)==abs(qu[t]-qu[i]))//在同一列或对角线 return false; return true; } void Show(int *qu, int len,int Count) { int i; cout<<"第"<<++Count<<"个解:"; for(i=0; i<len; i++)//i是行数 cout<<"("<<i<<", "<<qu[i]<<") "; cout<<endl; } int main() { initStack(st);//初始化 cout<<"皇后问题(n<20) n="; int n; cin>>n;//输入皇后数目 cout<<n<<"皇后问题求解如下:"<<endl; int cnt=0,row=0;//问题的解的数目、行 int *queen = new int ;//开辟动态数组保存每行皇后的列位置 queen[0]=-1;//最开始把首元素置为-1 Push(st,0);//把首位置压入栈 while(!StackEmpty(st))//栈非空 { GetTop(st,row);//row是当前栈顶元素值 queen[row]++;//尝试下一列 if(queen[row]>=n)//当前行的所有n列都已经尝试过,但是皇后没有摆放成功 Pop(st);//栈顶元素出栈,相当于回溯到上一行 else { if(Check(queen,row))//检查,如果能在该位置放皇后 { if(row==n-1)//试探到第n行 { Show(queen,n,cnt);//输出皇后位置 cnt++;//解法加一 } else//仍需要试探 { queen[row+1]=-1;//标记-1 Push(st,row+1);//皇后的位置压入栈 } } } } delete []queen;//释放动态数组 free(st);//销毁栈 return 0; }
运行结果:
思路:
queen[row]数组记录第row行上皇后的列位置;
st栈记录当前行数;
从第0行开始,依次试探0-n-1列;
当row==n-1说明全部成功放置皇后;
当queen[row]>=n说明当前行下,各列试探完毕,都不能成功放置,所以要回溯到上一行,将当前行出栈。
相关文章推荐
- 如何组织构建多文件 C 语言程序(二)
- 如何写好 C main 函数
- C#数据结构之顺序表(SeqList)实例详解
- Lua和C语言的交互详解
- Lua教程(七):数据结构详解
- 解析从源码分析常见的基于Array的数据结构动态扩容机制的详解
- C#数据结构之队列(Quene)实例详解
- C#数据结构揭秘一
- C#数据结构之单链表(LinkList)实例详解
- 关于C语言中参数的传值问题
- 简要对比C语言中三个用于退出进程的函数
- 深入C++中API的问题详解
- 基于C语言string函数的详解
- C语言中fchdir()函数和rewinddir()函数的使用详解
- C语言内存对齐实例详解
- C++基于栈实现铁轨问题
- C语言编程中统计输入的行数以及单词个数的方法
- C语言自动生成enum值和名字映射代码
- 使用C语言判断英文字符大小写的方法
- c语言实现的带通配符匹配算法