一道关于栈的问题

hyBegins 2005-03-20 02:47:13
编号分别为1,2,……,n的n辆列车顺序进入一个栈式结构的站台。试给出这n辆列车开出车站的所有可能次序。例如编号为1,2,3,4的4辆列车按照push,push,pop,push,push,pop,pop,pop操作,可使得开出车站的次序为2,4,3,1
...全文
144 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
Riemann 2005-03-23
  • 打赏
  • 举报
回复
楼上的弄错了,应该是C(2n,n)-C(2n,n-1)=C(2n,n)/(n+1).
minlingtianxia 2005-03-23
  • 打赏
  • 举报
回复
'an=C(2n,n)-C(2n,2n-1)=C(2n,n)/(n+1)'
有没有人把这个公式给推导一下?谢谢
kamimail 2005-03-21
  • 打赏
  • 举报
回复
每递归一次将当前结果存入链表中,到最后在从链表中取出结果
hyBegins 2005-03-21
  • 打赏
  • 举报
回复
我自己也从网上找了些资料,但只找到下面这个公式,具体怎么用程序输出每种可能的序列的算法,找不到。不知哪位能帮忙!
关于计数问题:即列车出站的顺序有多少种可能(记做an)?
n=1, an= 1
n=2, an= 2
n=3, an= 5
n=4, an=14
...... ......
an的通解an=C(2n,n)-C(2n,2n-1)=C(2n,n)/(n+1)
hyBegins 2005-03-21
  • 打赏
  • 举报
回复
晕啊,能给个详细点的算法吗?不要源程序呀
mmmcd 2005-03-21
  • 打赏
  • 举报
回复
输出每种可能的序列的算法就是用回溯法。
“栈顶元素有两个选择,要么出,要么不出”

这类问题提过n次(n>=5)
有时间看看这个:
http://acm.zju.edu.cn/show_problem.php?pid=1004
kamimail 2005-03-20
  • 打赏
  • 举报
回复
代码可能不简洁请指正啊
kamimail 2005-03-20
  • 打赏
  • 举报
回复
一个简单实现,思路见注释,我也是初学,请大家批评指正

// STack.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include "STack.h"
#include <stack>
#include <list>
#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// 唯一的应用程序对象

CWinApp theApp;

using namespace std;
//stack<int> plat;
int plsz=4;

//假设车站停位与车数一致
void Func(int num,stack<int> plat1,list<int> rsltset1)//处理当前编号为num 的车辆,栈顶元素有两个选择,要么出,要么不出
{

stack<int> plat(plat1);
list<int> rsltset(rsltset1);

if( num<plsz )
{
for(int i=0;i<2;i++)
{
if(i==0)
{

plat.push(num);//当前车入库

rsltset.push_back(plat.top());//出站
plat.pop();
Func(num+1,plat,rsltset);
rsltset.pop_back();

}
//当前栈顶选择不初,则处理下一辆车
else
{
plat.push(num);

//plat.push(num+1);

Func(num+1,plat,rsltset);
}

}
}
if(num==plsz) //如果当前车号为车库编号总数
{
plat.push(num);
while(!plat.empty())//剩余车辆存入结果集中
{
rsltset.push_back(plat.top());
plat.pop();

}
list<int>::iterator itr=rsltset.begin();
for(;itr!=rsltset.end();itr++)
{
cout<<(*itr)<<" ";
}

cout<<endl;
}

}
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
int nRetCode = 0;

// 初始化 MFC 并在失败时显示错误
if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
{
// TODO: 更改错误代码以符合您的需要
_tprintf(_T("致命错误: MFC 初始化失败\n"));
nRetCode = 1;
}
else
{
// TODO: 在此处为应用程序的行为编写代码。
stack<int> plat;list<int> rsltset;
Func(1,plat,rsltset);
int k;
cin>>k;
}

return nRetCode;
}
mmmcd 2005-03-20
  • 打赏
  • 举报
回复
#include <iostream.h>

int stk[21],out[21];

void go(int n,int intop,int outtop,int in)
{
if(intop==0 && outtop==n)
{
for(int i=0;i<n;i++)
cout<<out[i]<<' ';
cout<<endl;
return;
}

if(intop<n && in<n)
{
stk[intop]=in+1;
go(n,intop+1,outtop,in+1);
}

if(intop>0)
{
out[outtop]=stk[intop-1];
int t=stk[intop-1];
go(n,intop-1,outtop+1,in);
stk[intop-1]=t;
}
}

int main()
{
int n;
while(cin>>n && n<21)
go(n,0,0,0);
return 0;
}
zengwujun 2005-03-20
  • 打赏
  • 举报
回复
例子:进1234
那么,所有出现312,412,413,423的序列都是不可能出现的
zengwujun 2005-03-20
  • 打赏
  • 举报
回复
这里面只有一条规则

若p,q,r是顺序进栈的三个元素,那么出来的顺序不可能是r,p,q.
记住,是顺序进,而不是连续进

33,010

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧