C 每个可能建造的塔的算法
我需要用C语言创建一个程序,它应该执行以下操作: 给定n个非零的正数,我要打印出所有的塔,这些塔可以由给定的部分建造。只有一条规则-不能将较大的堆叠到较小的上(但可以堆叠两个相同大小的)。因此,如果给我3个数字,1 2 3,可能性是:C 每个可能建造的塔的算法,c,algorithm,C,Algorithm,我需要用C语言创建一个程序,它应该执行以下操作: 给定n个非零的正数,我要打印出所有的塔,这些塔可以由给定的部分建造。只有一条规则-不能将较大的堆叠到较小的上(但可以堆叠两个相同大小的)。因此,如果给我3个数字,1 2 3,可能性是: 3, 2, 1 3, 1 3, 2 3 2, 1 2 1 鉴于2 3,其: 3, 2, 2 3, 2 3 2, 2 2 有人能帮我吗?我试着研究递归算法、河内塔算法和相关算法,但我想不出这一点。据我所知,这个问题可以通过排序来简化。如果首先对数字数组进行排序,
3, 2, 1
3, 1
3, 2
3
2, 1
2
1
鉴于2 3,其:
3, 2, 2
3, 2
3
2, 2
2
有人能帮我吗?我试着研究递归算法、河内塔算法和相关算法,但我想不出这一点。据我所知,这个问题可以通过排序来简化。如果首先对数字数组进行排序,问题将减少到输入的所有子数组的输出。如果
n
表示输入中的元素数,这将导致2^n
可以递归枚举的可能子数组
但是,此解决方案要求将输入中大小相同的块视为不同的。如果大小相等的片段被认为是相等的,则应将输入排序,然后转换为成对的(s_i,m_i)
,其中s_i
表示第i
片段的大小,m_i
表示其多重性。然后,可以使用以下伪代码算法生成可能的解决方案
type piece = struct (integer, integer)
function enumerate( a array of piece )
{
if ( a is empty )
{
end current solution
}
else
{
let f = first element of a
for each i <= multiplicity of f
{
output size of f i times
enumerate ( a with first element removed )
}
}
}
type piece=struct(整数,整数)
函数枚举(片段数组)
{
如果(a为空)
{
终端电流解决方案
}
其他的
{
设f=a的第一个元素
对于每一个i开始按大小顺序排序,这意味着最大的一块是第一位的。现在考虑每一个相同的片段序列。
假设我们目前正在研究大小为a
的碎片。将所有这些碎片放在塔上
移动到下一个最大的尺寸(尺寸为b
,以便b
),并从这一点递归地建造所有可能的塔
塔架上是否至少有一块尺寸a
?如果有,请取出一块尺寸a
,然后返回步骤2
以下程序在ANSI C中实现了该算法。用户在命令行上输入片段。我们使用比较函数调用qsort
,将输入按降序排序,然后调用递归函数print\u tower
#include <stdlib.h>
#include <stdio.h>
/* Assumes that data is sorted in descending order. */
void print_tower(int *data, int n, int pos, int *result, int len) {
int seek, i;
/* If we're out of data, print the result pieces. */
if (pos == n) {
if (len > 0) {
printf("%d", result[0]);
for (i = 1; i < len; ++i) {
printf(", %d", result[i]);
}
printf("\n");
}
return;
}
/* Scan the sequence of identical elements. */
seek = pos;
while (seek < n && data[seek] == data[pos]) {
result[len++] = data[seek++];
}
/* Recursively print the tower and shorten the sequence. */
while (pos++ <= seek) {
print_tower(data, n, seek, result, len--);
}
}
/* Comparison function to sort integers in descending order. */
int reverse(const void *p, const void *q) {
int a = *(int *)p, b = *(int *)q;
return b - a;
}
int main(int argc, char **args) {
int i, n = argc-1,
*data = (int *) malloc(n*sizeof(int)),
*result = (int *) malloc(n*sizeof(int));
for (i = 0; i < n; ++i) {
data[i] = atoi(args[i+1]);
}
qsort(data, n, sizeof(int), reverse);
print_tower(data, n, 0, result, 0);
return 0;
}
#包括
#包括
/*假设数据按降序排序*/
无效打印塔(int*数据、int n、int pos、int*结果、int len){
int seek,我;
/*如果数据不足,请打印结果*/
如果(pos==n){
如果(len>0){
printf(“%d”,结果[0]);
对于(i=1;i while(pos++按大小对数组排序。然后(提示)您只能将“右”数组元素堆叠在“左”数组元素上。可能是有人搞错了;您的答案现在没有任何反对票>这似乎是合理的解决方案,但后者更简单,但谢谢,为了学习目的,我也会研究它:)