Problem:
MathJax.Hub.Config({
tex2jax: {inlineMath: [['$','$'], ['\\(','\\)']]}
});

D: パスワード

問題

AOR イカちゃんは英小文字のみからなる強力なパスワードを作りたいと思っています。
友達から $N$ 個の危険なパスワードの例を教えてもらった AOR イカちゃんは、
以下の条件を全て満たすようなパスワードを作ることにしました。

長さは1文字以上である。

どの危険なパスワードの、どの連続した部分文字列とも異なる。

1, 2 の条件を満たした中で、最も短い文字列である。

1,2,3の条件を満たした中で、辞書順に並べたとき先頭に来る文字列である。

AOR イカちゃんに代わって強力なパスワードを生成するプログラムを書いてください。

入力

入力は以下の形式で標準入力から与えられる。

$N$

$S_1$

$\vdots$

$S_N$

1 行目には、文字列の数を表す整数 $N$ が与えられる。

2 行目からの $N$ 行には、文字列 $S_i$ が与えられる。

$|S_i|$ とは文字列の長さであり、1 文字以上である。

$1 \le N \le 100,000$ を満たす。

$1 \le \sum_{1\le i \le N} |S_i| \le 400,000$ を満たす。

文字列は英小文字のみを含む。

出力

答えを 1 行で出力せよ。また、末尾に改行も出力せよ。

サンプル

サンプル入力 1

5
password
login
admin
root
master

サンプル出力 1

b

サンプル入力 2

3
abcdefghijklmnopqrstuvwxy
qwertyuiopasdfghjklxcvbnm
qawsxedcrfvtgbyhnujmikolp

サンプル出力 2

z

サンプル入力 3

1
abcdefghijklmnopqrstuvwxyz

サンプル出力 3

aa

Solution in C++11 (judge verdict: Time Limit Exceeded)

#include<bits/stdc++.h>

using namespace std;

int main()
{
  int N;
  string S[100000];
  vector< pair< int, int > > vc[26];

  cin >> N;
  for(int i = 0; i < N; i++) {
    cin >> S[i];
    for(int j = 0; j < S[i].size(); j++) {
      vc[S[i][j] - 'a'].emplace_back(i, j);
    }
  }

  queue< string > que;
  for(int i = 'a'; i <= 'z'; i++) {
    string nxt = string(1, i);
    que.push(nxt);
    bool match = false;
    for(auto &j : vc[nxt[0] - 'a']) {
      if(j.second + nxt.size() > S[j.first].size()) continue;
      if(S[j.first][j.second + nxt.size() - 1] == i) match = true;
    }
    if(!match) {
      cout << nxt << endl;
      return (0);
    }
  }

  string tt;

  while(!que.empty()) {
    string p = que.front();
    que.pop();
    for(char i = 'a'; i <= 'z'; i++) {
      string nxt = p + string(1, i);
      bool match = false;
      for(auto &j : vc[nxt[0] - 'a']) {
        if(j.second + nxt.size() > S[j.first].size()) continue;
        int ptr = j.second;
        while(ptr - j.second < nxt.size() && S[j.first][ptr] == nxt[ptr - j.second]) ++ptr;
        if(ptr - j.second == nxt.size()) {
          match = true;
          break;
        }
      }
      if(match) {
        que.push(nxt);
      } else {
        cout << nxt << endl;
        return (0);
      }

    }
  }

}