ZOJ1002 Fire Net(非递归版)
以前用递归的回溯搜索思路做过一次,参见ZOJ1002 Fire Net(递归版),今天想着用非递归的方法试试看,呵呵,比我想象中要难啊,主要还是堆栈里究竟放什么,这一点上思路一直没理清。因此用了整整一天的时间,总算用非递归的方法把1002给AC掉了,在代码中我引入了堆栈层次的概念,模拟系统堆栈的行为,并且在搜索时加入了剪枝,但代码写得还是很烂,继续思考如何改进。
Written by : phinecos(洞庭散人)
Data : 2/11/2008 16:30
Description: 非递归,模拟系统堆栈解决类似八皇后问题
State : Accepted
Run Time: 0ms
Run Memory: 184KB
****************************************/
#include<iostream>
#include <stack>
using namespace std;
const int MAXSIZE = 4;// 地图最大大小
char map[MAXSIZE][MAXSIZE];// 地图
int maxNum,n;
struct Node
{
int row;//行
int col;//列
int level;//当前层次
};
bool CanPut(int row, int col)
{//测试是否可以放置碉堡到row行col列处,因为位置是从小到大前进的,因此只需要测试比待测试点小的位置
int i;
//测试col列上是否有面对面的碉堡
for (i = row - 1; i >= 0; --i)
{
if (map[i][col] == 'O') return false;
if (map[i][col] == 'X') break;
}
//测试row行上是否有面对面的碉堡
for (i = col - 1; i >= 0; --i)
{
if (map[row][i] == 'O') return false;
if (map[row][i] == 'X') break;
}
return true;
}
void Solve(int k,int curNum)
{
stack<Node> s1;//解决树堆栈
Node node;
int row,col,i;
int curLevel = 0;//当前层次
//起始结点入栈
node.row=k/n;
node.col = k%n;
node.level = curLevel;//当前堆栈层次是第0层
s1.push(node);
while (!s1.empty())
{
node = s1.top();
row = node.row;
col = node.col;
if (map[row][col]=='.'&&CanPut(row,col)==true)
{//map[row][col]空闲并且经测试可以放置,则占据此位置
map[row][col] = 'O';
//堆栈层次加1
curLevel++;
node.level = curLevel;//作为这个堆栈层此的排头兵
s1.pop();
s1.push(node);
curNum++;//放置的棋子数目加1
}
if (row==n-1&&col==n-1)
{//来到这个堆栈层的最后一个结点了
if (curNum>maxNum)
{//保存这一层的最大数目
maxNum = curNum;
}
if (curLevel==0)
{//若回到第0层,则说明已经考虑完所有情况了
break;
}
/*
*下面这段代码非常低级趣味,我居然用了两重while循环,It's rubbish,不喜勿进!!!!
*/
//去掉当前堆栈层
while (!s1.empty())
{
node = s1.top();
if (node.level==curLevel)
{
s1.pop();
--k;
}
else
{
curLevel--;
curNum--;
break;
}
}
//有一种情况是栈此时是空的,但还是需要将层次数和棋子数减1,因为循环中它给跳过去了。。。汗。
if(s1.empty())
{
curLevel--;
curNum--;
}
//将上一层的排头兵恢复回来(就是把'O'再此变回'.',并且层次改为这一层)
++k;
row = k/n;
col = k%n;
map[row][col] = '.';
node.row = row;
node.col = col;
node.level = curLevel;
s1.push(node);
//以上一层排头兵的下一个结点为起点,继续
if (k+1<n*n)
{
++k;
node.row = k/n;
node.col = k%n;
node.level = curLevel;
s1.push(node);
}
else
{//当来到最后一个元素时,又有一个特殊的情形,此时当前层次所有情况都已经考虑完毕,因此需要将当前堆栈层给清空掉,哎,这个清空动作和前面是一样的,可居然又单独列了遍代码,吐了。。。
if (curLevel==0)
{
break;
}
while (!s1.empty())
{
node = s1.top();
if (node.level==curLevel)
{
s1.pop();
--k;
}
else
{
curLevel--;
curNum--;
break;
}
}
if (s1.empty())
{
curLevel--;
curNum--;
}
++k;
row = k/n;
col = k%n;
map[row][col] = '.';
node.row = row;
node.col = col;
node.level = curLevel;
s1.push(node);
++k;
node.row = k/n;
node.col = k%n;
node.level = curLevel;
s1.push(node);
}
}
else
{//还没来到这一堆栈层次的最后一个节点,继续吧
++k;
node.row = k/n;
node.col = k%n;
node.level = curLevel;
s1.push(node);
}
}
}
int main()
{
int i,j;
while(cin>>n&&n!=0)
{
//输入地图
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
cin>>map[i][j];
}
}
maxNum=0;//最多可能放置的数目
//开始深搜,起点设置为左上角
Solve(0,0);
cout<<maxNum<<endl;
}
return 0;
}
ZOJ1002 Fire Net(非递归版)相关推荐
- 图解二叉树非递归版的中序遍历算法
你会学到什么 讨论的问题是什么 这个问题相关的概念和理论 非递归版中序遍历算法 代码思考 算法技巧 实现代码 快照 评价算法 总结 欢迎关注算法思考与应用公众号 你会学到什么? 树的递归遍历算法很容易 ...
- 八皇后问题(非递归版)
复制代码#include <iostream> #include <stack> using namespace std; const int MAXSIZE = 8;//棋盘 ...
- 图解二叉树非递归版的前序遍历算法
" 图解用栈数据结构对树的前序遍历,中序遍历,后续遍历." 树的遍历 所谓遍历 (Traversal) 是指沿着某条搜索路线,依次对树中每个结点均做一次且仅做一次访问.访问结点所做 ...
- hdu 4850 字符串构造---欧拉回路构造序列 递归+非递归实现
http://acm.hdu.edu.cn/showproblem.php? pid=4850 题意:构造长度为n的字符序列.使得>=4的子串仅仅出现一次 事实上最长仅仅能构造出来26^4+4- ...
- 2021 - 10 -7 ! 二叉树的前序、中序、后序遍历 非递归思路(迭代版本)
//! 前序遍历的非递归版本,精髓在于用栈模拟递归的过程,但实际进栈出栈顺序与递归并不一样, //! 比较抽象,建议画图理解,比较重要 void BinarySearchTreesZH::preord ...
- 语言非递归求解树的高度_算法素颜(11):无死角“盘”它!二分查找树
引言 <菜鸟也能"种"好二叉树!>一文中提到了:为了方便查找,需要进行分层分类整理.而满足这种目标的数据结构之一就是树. 树的叶子节点可以看作是最终要搜寻的目标物:叶子 ...
- 实现一个二叉树层级遍历_算法总结:左神class5—二叉树递归和非递归实现遍历(后序用一个栈彩蛋)...
二叉树类型的题目为常考题型 1.能够结合队列.栈.链表.字符串等很多数据结构. 2.需要掌握图的基本遍历方式,比如BFS和DFS. 3.需要掌握递归函数的使用,并自己设计出递归过程. 4.与实际工作结 ...
- Binary Tree 非递归遍历模板小结(经典!)
Binary Tree的遍历可分为preorder, inorder, postorder和in-level order四种.前3种可用递归或非递归(基于stack,后进先出),第4种通常用BFS,基 ...
- n皇后问题 递归和非递归
问题引入 八皇后问题 八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例.该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇 ...
最新文章
- c# lock (obj) 与 lock (this) 区别
- [LeetCode]--63. Unique Paths II
- python文件打开的合法方式-用python与文件进行交互的方法
- 如何看待小米10的葫芦屏?
- 应用程序框架实战二十六:查询对象
- 多线程中抛异常的这个面试题你会吗?
- html图片下方会有一像素,div里嵌套了img底部会有白块问题和图片一像素问题解决 - Macchiato...
- hdu 1241Oil Deposits(dfs模板)
- Spinnaker:云原生多云环境持续部署的未来
- 编辑请求内容 Charles
- VB连接ACCESS数据库精简版
- 万圣节html代码大全,《方舟 生存进化》万圣节代码大全一览
- 360 os3.0 android7.1,【360 N6 Pro】360OS安卓7.1系统V3.0.087付费纯净版ROOT刷机包
- 卷积神经网络原理简述
- 确定有限自动机DFA和非确定有限自动机NFA
- All the python knowledge that I come across
- bae java mysql_在百度bae云平台中使用JAVA连接MySQL数据库
- Android_GestureDetector手势滑动使用
- [1191]电脑耳机孔插上耳机没反应
- nav 计算机网络_Wi-Fi 6(802.11ax)解析9:双重NAV技术(Dueling NAVs)
热门文章
- bug诞生记——不定长参数隐藏的类型问题
- GCC中通过--wrap选项使用包装函数
- C++/C++11中头文件numeric的使用
- 图片像素、英寸、厘米之间的单位换算
- 【C++】google glog详解
- java instanceof 报错_java instanceof方法
- python 区域和检索_304. 二维区域和检索(Python)
- python cv2 轮廓的包络 面积_Python 基于FIR实现Hilbert滤波器求信号包络详解
- Fastlane- app自动编译、打包多个版本、上传到app store
- vue调试工具如何使用_教你使用Vue.js的DevTools来调试vue项目