大赛一个关于纸牌排列问题,求各位帮助。用C/C++实现
时间:2011-09-13
来源:互联网
1.Cards
Tom 手上有N张纸牌,每张牌都有唯一的编号,编号由1到N。一开始纸牌叠放在一
起,按编号小的在上大的在下。整副牌放在C处,然后Tom每次拿起最上面的牌,然后放
在B处或A处,在此期间,Tom还可以将B处最上面的牌放到A处。最后,所有的牌都到
了A处。若顺序不同,则最后A处的牌的排列是不一样的。
例如,有三张牌,通过以下步骤,最后从上到下的排列为:2 3 1
Tom很想知道到底能产生多少种排列,于是他叫你帮忙。
Input:
每行为一个正整数N( N <= 10 ),表示纸牌的数目。N = 0表示结束
Output:
对于每个N,将所有可以产生的纸牌的排列显示出来,一个排列是A处纸牌由顶到底
的顺序。将所有的排列按词典顺序输出,然后输出一行空行。注意!一个排列中,编号之间
有一个空格,而最后一个编号之后是没有空格的!
Sample input:
1
3
0
Sample output:
1
1 2 3
1 3 2
2 3 1
3 1 2
3 2 1
Tom 手上有N张纸牌,每张牌都有唯一的编号,编号由1到N。一开始纸牌叠放在一
起,按编号小的在上大的在下。整副牌放在C处,然后Tom每次拿起最上面的牌,然后放
在B处或A处,在此期间,Tom还可以将B处最上面的牌放到A处。最后,所有的牌都到
了A处。若顺序不同,则最后A处的牌的排列是不一样的。
例如,有三张牌,通过以下步骤,最后从上到下的排列为:2 3 1
Tom很想知道到底能产生多少种排列,于是他叫你帮忙。
Input:
每行为一个正整数N( N <= 10 ),表示纸牌的数目。N = 0表示结束
Output:
对于每个N,将所有可以产生的纸牌的排列显示出来,一个排列是A处纸牌由顶到底
的顺序。将所有的排列按词典顺序输出,然后输出一行空行。注意!一个排列中,编号之间
有一个空格,而最后一个编号之后是没有空格的!
Sample input:
1
3
0
Sample output:
1
1 2 3
1 3 2
2 3 1
3 1 2
3 2 1
作者: a8639197 发布时间: 2011-09-13
为A B C开设 3 个栈,分别是 StackA StackB StackC;
再设一个栈集合 StackSet;
算法初始化:把 N,N-1,...,3,2,1 压入 StackC;把 StackA StackB 和 StackSet 置空;
调用 Doit();
输出 StackSet;
算法结束.
核心算法如下:
void Doit()
{
int i,x;
if (StackC 为空)
{
令 StackB 有 m 个元素;
for (i=1;i<=m;i++)
{
从 StackB 弹出元素,送入 x;
把 x 压入 StackA;
}
if (StackSet 没有与 StackA 重复的元素) 把 StackA 内容放入 StackSet;
for (i=1;i<=m;i++)
{
从 StackA 弹出元素,送入 x;
把 x 压入 StackB;
}
}
else
{
从 StackC 弹出元素,送入 x;
把 x 压入 StackB;
Doit();
从 StackB 弹出元素,扔掉;
把 x 压入 StackA;
Doit();
从 StackA 弹出元素,扔掉;
if (StackB 不空)
{
从 StackB 弹出元素,送入 x;
把 x 压入 StackA;
Doit();
从 StackA 弹出元素,扔掉;
把 x 压入 StackB;
}
}
}
再设一个栈集合 StackSet;
算法初始化:把 N,N-1,...,3,2,1 压入 StackC;把 StackA StackB 和 StackSet 置空;
调用 Doit();
输出 StackSet;
算法结束.
核心算法如下:
void Doit()
{
int i,x;
if (StackC 为空)
{
令 StackB 有 m 个元素;
for (i=1;i<=m;i++)
{
从 StackB 弹出元素,送入 x;
把 x 压入 StackA;
}
if (StackSet 没有与 StackA 重复的元素) 把 StackA 内容放入 StackSet;
for (i=1;i<=m;i++)
{
从 StackA 弹出元素,送入 x;
把 x 压入 StackB;
}
}
else
{
从 StackC 弹出元素,送入 x;
把 x 压入 StackB;
Doit();
从 StackB 弹出元素,扔掉;
把 x 压入 StackA;
Doit();
从 StackA 弹出元素,扔掉;
if (StackB 不空)
{
从 StackB 弹出元素,送入 x;
把 x 压入 StackA;
Doit();
从 StackA 弹出元素,扔掉;
把 x 压入 StackB;
}
}
}
作者: icessl 发布时间: 2011-09-14
这个问题其实就是在问:
给你一个栈(原题目中的B),按顺序向其中 push ,随意从其中 pop 。求可能得到的所有输出队列。
首先,总的组合数是 Catalan 数(去查 wiki 和 wolfram 能够得到详细信息)。
其次,根据上面的问题“翻译”,你可以写出一个递归实现来做这件事。
BTW, Catalan 数增长的很快,这也就是限制 n<=10 的原因。你可以从参考资料中得到该数值的大小。
给你一个栈(原题目中的B),按顺序向其中 push ,随意从其中 pop 。求可能得到的所有输出队列。
首先,总的组合数是 Catalan 数(去查 wiki 和 wolfram 能够得到详细信息)。
其次,根据上面的问题“翻译”,你可以写出一个递归实现来做这件事。
BTW, Catalan 数增长的很快,这也就是限制 n<=10 的原因。你可以从参考资料中得到该数值的大小。
作者: Leaveye 发布时间: 2011-09-14
相关阅读 更多
热门阅读
-
office 2019专业增强版最新2021版激活秘钥/序列号/激活码推荐 附激活工具
阅读:74
-
如何安装mysql8.0
阅读:31
-
Word快速设置标题样式步骤详解
阅读:28
-
20+道必知必会的Vue面试题(附答案解析)
阅读:37
-
HTML如何制作表单
阅读:22
-
百词斩可以改天数吗?当然可以,4个步骤轻松修改天数!
阅读:31
-
ET文件格式和XLS格式文件之间如何转化?
阅读:24
-
react和vue的区别及优缺点是什么
阅读:121
-
支付宝人脸识别如何关闭?
阅读:21
-
腾讯微云怎么修改照片或视频备份路径?
阅读:28