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 JAVA (judge verdict: Wrong Answer)

import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedList;
import java.util.ListIterator;
import java.util.PriorityQueue;
import java.util.Scanner;

public class Main {

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);

		while (true) {
			final int N = sc.nextInt();

			if (N == 0) {
				break;
			}

			String[] array = new String[N];
			for (int i = 0; i < N; i++) {
				array[i] = sc.next();
			}

			Arrays.sort(array);

			for (int count = 0; count < N - 1; count++) {
				int cur_num = -1;
				int con_num = -1;
				int rest = -1;
				boolean order = true;
				
				for (int i = 0; i < N; i++) {
					if("".equals(array[i])){
						continue;
					}
					
					char[] moto = array[i].toCharArray();

					for (int j = i + 1; j < N; j++) {
						if ("".equals(array[j])) {
							continue;
						}

						char[] con = array[j].toCharArray();

						final int len = Math.min(moto.length, con.length);

						//
						{
							int ll = -1;
							LOOP: for (int l = 0; l < len; l++) {
								for (int c = l; c >= 0; c--) {
									if (moto[moto.length - 1 - c] != con[l - c]) {
										continue LOOP;
									}
								}

								ll = l;
							}

							if (rest < ll) {
								order = true;
								cur_num = i;
								con_num = j;
								rest = ll;
							}
						}

						//
						{
							int ll = -1;
							LOOP: for (int l = 0; l < len; l++) {
								for (int c = l; c >= 0; c--) {
									if (con[con.length - 1 - c] != moto[l - c]) {
										continue LOOP;
									}
								}

								ll = l;
							}

							if (rest < ll) {
								order = false;
								cur_num = i;
								con_num = j;
								rest = ll;
							}
						}
					}
				}
				
				/*System.out.println(array[cur_num] + " " + array[con_num] + " "
						+ rest + " " + order);*/
				
				if(rest == -1){
					continue;
				}
				
				rest++;
				
				try{
				if (order) {
					array[cur_num] = array[cur_num].substring(0,
							array[cur_num].length() - rest)
							.concat(array[con_num]);
				} else {
					array[cur_num] = array[con_num].substring(0,
							array[con_num].length() - rest)
							.concat(array[cur_num]);
				}
				}catch(Exception e){
					System.err.println(array[cur_num] + " " + array[con_num] + " "
							+ rest + " " + order);
				}
				
				array[con_num] = "";
				Arrays.sort(array);
			}

			for(String str : array){
				if(!"".equals(str)){
					System.out.println(str);
					break;
				}
			}
		}

		sc.close();
	}

}