Problem:
Princess, a Cryptanalyst

お姫様の暗号解読

English text is not available in this practice contest.

ある貧乏な国のおてんばで勇敢なお姫様は，お忍びで出かけた町である日本語で書かれた古文書を手に入れた．お姫様は日本語ができるため，さっそくこの古文書を読んでみた．すると，驚くべき事が分かった．この古文書は，古の秘宝の在処を示していたのである．ところが，秘宝の在処は暗号になっており，容易には分からないようになっていた．そこでお姫様は，従者であるあなたに暗号の解読を手伝うように命令を下した．

あなたはお姫様を助けるため昼夜を問わず調査を行った．その結果，Shortest Secret String (SSS) と呼ばれる文字列が解読に重要な役割を果たすことがわかった．ここで SSS とは，N 個の単語全部を部分文字列として含み，なおかつその長さが最小であるような文字列である．

あなたの仕事は，N 個の単語から SSS を見つけ出す事である．

Input

入力は複数のデータセットで与えられる．データセットの初めの一行は，データセットに含まれる単語の数N(1≦N≦10)が与えられる．続くN行に単語が与えられる．最後のデータセットの後に，0のみを含む一行が与えられる．

なお，入力で与えられる単語はアルファベット小文字のみからなり，長さは高々10であることが保証されている．

Output

各データセットについてSSS を一行に出力せよ．また，複数ある場合は辞書式順序で最小のものを出力せよ．

Sample Input

4
apple
length
things
thin
2
icp
cpc
3
zeta
eta
alphabet
2
until
till
0

Output for the Sample Input

applengthings
icpc
zetalphabet
untill

Solution in C (judge verdict: Time Limit Exceeded)

/*
  AOJ 2022
  Title:Princess, a Cryptanalyst
  @kankichi573
  14/6/19 TLE
*/
#include <stdio.h>
#include <string.h>

#define min(x,y) (((x)<(y))?(x):(y))
int n;
int min_;
char words[10][11];
char min_str[101];

void shortest_connect(char *in1,char *in2,char *ret)
{
  int i,len;

  if(strstr(in1,in2))
    {
      strcpy(ret,in1);
      return;
    }
  if(strstr(in2,in1))
    {
      strcpy(ret,in2);
      return;
    }
  len=strlen(in1);
  
  for(i=len-1;i>0;i--)
    if(0==strncmp(in1+len-i,in2,i))
      {
	strcpy(ret,in1);
	strcat(ret,in2+i);
	return;
      }
  
  if(in1[len]==in2[0])
    {
      strncpy(ret,in1,len);
      strcat(ret,in2+1);
      return;
    }
  strcpy(ret,in1);
  strcat(ret,in2);

}
void solve(int use,int no,char *acc)
{
  int i,len,mask;
  char ret[100];
#ifdef DEBUG
  printf("s> %d %s\n",use,acc);
#endif
  if(no==0)
    {
	if((len=strlen(acc))<min_)
	  {
	      min_=len;
	      strcpy(min_str,acc);
	      return;
	  }
    }
   else
    for(i=0;i<n;i++)
      {
	mask = 1<<i;
	if(use & mask)
	  {
	    shortest_connect(acc,&words[i][0],ret);
	    solve(use^mask,no-1,ret);
	  }
      }
}

main()
{
  int i;
  int use;
  char acc[100];


  while(scanf("%d",&n) && n)
    {
      for(i=0;i<n;i++)
	scanf("%s",&words[i][0]);
      use= (1<<n)-1;
      min_=101;
      acc[0]='\0';
      solve(use,n,acc);
      printf("%s\n",min_str);
    }

  return(0);
  
}