我遇到了一个无法解决的问题。我认为很多解决方案,但似乎没有人工作。
这就是我的问题:
你给了n 1 ,n 2 ,.... n k LEGO,每个都有一个偶数面孔。
只有在以下情况下,每个乐高可以再叠加一个:
上层乐高与其下的乐高相同;
上层乐高必须有多个面数小于或等于其下方乐高的面数。
除此之外,每个面都有一个相对的面,在第一个面之后通过输入插入; 例如:LEGO1 - face1,face2,face3,face4(face1和face2是face3和face4等对立面)。
该问题要求使用这些乐高积木使用每个乐高只有一次最高塔。 塔必须只有一个方向,所以它只能从左到右或从下到上。
非常感谢,抱歉我的英语不好:/
输入示例:
Lego1 - f1,f2,f3,f4,f5,f6
Lego2-f33,f47,f98,f123
Lego3 - f4,f127
输出示例:
2
答案 0 :(得分:1)
类似我很久以前的任务。算法的想法是:
当列表变空时你有一个可能的乐高序列。算法仅使用每个列表元素构建所有可能的序列。
工作代码:
#include <stdio.h>
#define MAX 4
struct CList{
int d;
struct CList *next;
};
void search(struct CList *pstart);
void result(struct CList *v[MAX], const int nv);
int main(){
static struct CList lst[MAX];
struct CList *p = lst;
int i;
for( i = 0; i < MAX - 1; i++){
lst[i].d = i;
lst[i].next = lst + i + 1;
}
lst[MAX-1].d = MAX - 1;
lst[MAX-1].next = lst;
search( p );
return 0;
}
void search(struct CList *pstart){
struct CList *p, *pp;
static struct CList *v[MAX];
static int nv = 0;
if( pstart->next == pstart ){
v[nv++] = pstart;
result( v, nv );
nv--;
return;
}
nv++;
p = pstart;
do{
pp = p;
p = p->next;
v[nv-1] = p;
pp->next = p->next;
search( pp );
p->next = pp->next;
pp->next = p;
} while( p != pstart );
nv--;
}
void result(struct CList *v[MAX], const int nv){
int i;
for( i = 0; i < nv; i++ ){
printf(" %d ", v[i]->d);
}
puts( "" );
}
在你的情况下,可能会进行进一步的优化(例如,在当前元素dosn堆叠时打破递归)。