我有一个无法解决的问题。我想过很多解决方案,但似乎没人能解决。

这就是我的问题:

您会得到n1,n2,.... nk个乐高积木,每个积木都有偶数个面孔。
只有在以下情况下,每个乐高积木才能堆叠在一起:


上层乐高与下层乐高具有相同的外观;
上部乐高的面部数量必须小于或等于其下方的乐高的面部数量。


除此之外,每个面都有一个相反的面,该面通过输入在第一个面之后插入;
例如:LEGO1-face1,face2,face3,face4(face1和face2是相反的,例如face3和face4)。

问题要求使用每个乐高积木仅用这些乐高积木建造最高的塔。
塔必须只有1个方向,因此只能从左到右或从下到上移动。

非常感谢,对不起我的英语不好:/

输入示例:

乐高1-f1,f2,f3,f4,f5,f6

乐高2- f33,f47,f98,f123

乐高3-F4,F127

输出示例:

2

最佳答案

类似于我很久以前的任务。该算法的思想是:


将项目(乐高)放入循环列表(封闭式单链列表)中;
使功能

循环中

从列表中获取下一个元素(将其删除)
递归校准自己
插入先前删除的元素
前进到下一个元素




当列表为空时,您可能获得了一种乐高序列。算法仅使用每个列表元素构建一次所有可能的默认情况。

工作代码:

#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( "" );
}


在您的情况下,可能可以进行进一步的优化(例如,当当前元素不堆叠时中断递归)。

09-26 04:18