LiveArchive 4994 Overlapping Scenes

解法
入力の文字列を next_permutation() して、順に重ねあわせていく。2つの文字列に対して重ね合わせをして、末尾文字列から一致した部分を引いたものを返す関数 concat() を用意した。

#include <bits/stdc++.h>

using namespace std;

#define REP(i,a,b) for(int i=a;i<b;i++)
#define rep(i,n) REP(i,0,n)

#define chmin(a,x) a=min(a,x)

int const INF = 1<<29;

string concat(string const& now, string const& suffix) {
  
  int const now_len = now.size();
  int const suf_len = suffix.size();
  
  int clen = -1;
  rep(i, now_len) {
    rep(j, suf_len) {
      if(now[i+j] != suffix[j]) { break; }
      if(i+j >= now_len-1) { clen = j+1; goto OK; }
    }
  }

  return suffix;
  
 OK:;
  return suffix.substr(clen);
  
}

int main() {
  
  int Tc; cin >> Tc;
  rep(tc, Tc) {
    int N; cin >> N;
    
    cout << "Case " << tc + 1 << ": ";
    
    string strs[N];
    rep(i, N) cin >> strs[i];
    sort(strs, strs+N);
    
    int mnlen = INF;
    do {
      string now;
      rep(i, N) {
        now += concat(now, strs[i]);
      }
      chmin(mnlen, (int)now.size());
    } while(next_permutation(strs, strs+N));
    
    cout << mnlen << endl;
  }
  
  return 0;
}