Problem p01147 (C++) — buggy submission, verdict: Memory Limit Exceeded

#include <algorithm>
#include <cfloat>
#include <cmath>
#include <iostream>
#include <queue>
#include <stack>
#include <stdio.h>
#include <string>
#include <vector>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;

struct Info {
  short state;
  short num_used, total_length;
  ll order;
};

int N, match_len[10][10], POW[12];
char first_words[10][11], words[10][11];

bool strCmp(char *base, char *comp) {
  int length1, length2;
  for (length1 = 0; base[length1] != '\\0'; length1++)
    ;
  for (length2 = 0; comp[length2] != '\\0'; length2++)
    ;
  if (length1 != length2)
    return false;

  for (int i = 0; base[i] != '\\0'; i++) {
    if (base[i] != comp[i])
      return false;
  }
  return true;
}

void strcpy(char *to, char *str) {
  for (int i = 0; str[i] != '\\0'; i++) {
    to[i] = str[i];
    to[i + 1] = '\\0';
  }
}

int strCmp2(char *left, char *right) {
  int i;

  if (strCmp(left, right))
    return 3;

  for (i = 0; left[i] != '\\0' && right[i] != '\\0'; i++) {
    if (left[i] != right[i]) {
      if (left[i] < right[i])
        return 1;
      else {
        return 2;
      }
    }
  }
  if (left[i] == '\\0')
    return 1;
  else {
    return 2;
  }
}

void func() {

  int words_index = 0, first_length[N], second_length[N];

  int tmp;

  for (int i = 0; i < N; i++) {
    scanf("%s", first_words[i]);
    for (tmp = 0; first_words[i][tmp] != '\\0'; tmp++)
      ;
    first_length[i] = tmp;
  }

  int i_index, k_index, delete_num = 0;
  bool FLG;

  for (int i = 0; i < N; i++) {

    FLG = true;

    for (int k = 0; k < N; k++) {
      if (first_words[k][0] == '\\0')
        continue;
      if (i != k && first_length[i] <= first_length[k]) {

        for (int start = 0; start + first_length[i] <= first_length[k];
             start++) {

          for (i_index = 0, k_index = 0;
               i_index < first_length[i] &&
               first_words[i][i_index] == first_words[k][start + k_index];
               i_index++, k_index++)
            ;

          if (i_index == first_length[i]) {
            FLG = false;
            break;
          }
        }
      }
      if (!FLG)
        break;
    }

    if (FLG) {
      second_length[words_index] = first_length[i];
      strcpy(words[words_index++], first_words[i]);
    } else {
      first_words[i][0] = '\\0';
      delete_num++;
    }
  }

  N -= delete_num;

  int common, tmp_common;

  for (int left = 0; left < N; left++) {
    for (int right = 0; right < N; right++) {
      if (left != right) {

        common = 0;

        for (int start = 0; start < second_length[left]; start++) {
          for (tmp_common = 0;
               tmp_common < second_length[right] &&
               start + tmp_common < second_length[left] &&
               words[left][start + tmp_common] == words[right][tmp_common];
               tmp_common++)
            ;

          if (start + tmp_common == second_length[left]) {
            common = tmp_common;
            break;
          }
        }

        match_len[left][right] = common;
      }
    }
  }

  queue<Info> Q;

  for (int i = 0; i < N; i++) {
    Info new_info;
    new_info.state = POW[i];
    new_info.num_used = 1;
    new_info.order = i;
    new_info.total_length = second_length[i];
    Q.push(new_info);
  }

  int ans = BIG_NUM;

  char ans_word[101], tmp_word[101];
  int work[N];
  stack<int> S;

  while (!Q.empty()) {

    if (Q.front().num_used == N) {

      if (ans >= Q.front().total_length) {

        ll work_num = Q.front().order;
        for (int i = 0; i < N; i++) {
          S.push(work_num % 10);
          work_num /= 10;
        }

        for (int i = 0; i < N; i++) {
          work[i] = S.top();
          S.pop();
        }

        strcpy(tmp_word, words[work[0]]);
        int index = second_length[work[0]];

        int pre = work[0];

        for (int i = 1; i < N; i++) {
          for (int k = match_len[pre][work[i]]; words[work[i]][k] != '\\0';
               k++) {
            tmp_word[index++] = words[work[i]][k];
          }
          pre = work[i];
        }

        tmp_word[Q.front().total_length] = '\\0';

        if (ans > Q.front().total_length) {
          ans = Q.front().total_length;
          strcpy(ans_word, tmp_word);
        } else {
          if (strCmp2(ans_word, tmp_word) == 2) {
            strcpy(ans_word, tmp_word);
          }
        }
      }
      Q.pop();
    } else if (Q.front().total_length >= ans) {
      Q.pop();
    } else {

      for (int i = 0; i < N; i++) {
        if (!(Q.front().state & (1 << i))) {
          Info new_info;
          new_info.state = Q.front().state + POW[i];
          new_info.num_used = Q.front().num_used + 1;
          new_info.order = 10 * Q.front().order + i;
          new_info.total_length = Q.front().total_length + second_length[i] -
                                  match_len[Q.front().order % 10][i];
          Q.push(new_info);
        }
      }
      Q.pop();
    }
  }

  printf("%s\\n", ans_word);
}

int main() {

  for (int i = 0; i < 12; i++)
    POW[i] = pow(2, i);

  while (true) {
    scanf("%d", &N);
    if (N == 0)
      break;

    func();
  }

  return 0;
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <cfloat>
#include <cmath>
#include <iostream>
#include <queue>
#include <stack>
#include <stdio.h>
#include <string>
#include <vector>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;

struct Info {
  short state;
  short array[10], num_used, total_length;
};

int N, match_len[10][10], POW[12];
char first_words[10][11], words[10][11];

bool strCmp(char *base, char *comp) {
  int length1, length2;
  for (length1 = 0; base[length1] != '\\0'; length1++)
    ;
  for (length2 = 0; comp[length2] != '\\0'; length2++)
    ;
  if (length1 != length2)
    return false;

  for (int i = 0; base[i] != '\\0'; i++) {
    if (base[i] != comp[i])
      return false;
  }
  return true;
}

void strcpy(char *to, char *str) {
  for (int i = 0; str[i] != '\\0'; i++) {
    to[i] = str[i];
    to[i + 1] = '\\0';
  }
}

int strCmp2(char *left, char *right) {
  int i;

  if (strCmp(left, right))
    return 3;

  for (i = 0; left[i] != '\\0' && right[i] != '\\0'; i++) {
    if (left[i] != right[i]) {
      if (left[i] < right[i])
        return 1;
      else {
        return 2;
      }
    }
  }
  if (left[i] == '\\0')
    return 1;
  else {
    return 2;
  }
}

void func() {

  int words_index = 0, first_length[N], second_length[N];

  int tmp;

  for (int i = 0; i < N; i++) {
    scanf("%s", first_words[i]);
    for (tmp = 0; first_words[i][tmp] != '\\0'; tmp++)
      ;
    first_length[i] = tmp;
  }

  int i_index, k_index, delete_num = 0;
  bool FLG;

  for (int i = 0; i < N; i++) {

    FLG = true;

    for (int k = 0; k < N; k++) {
      if (i != k && first_length[i] <= first_length[k]) {

        for (int start = 0; start + first_length[i] <= first_length[k];
             start++) { // K??????????§????????????????

          for (i_index = 0, k_index = 0;
               i_index < first_length[i] &&
               first_words[i][i_index] == first_words[k][start + k_index];
               i_index++, k_index++)
            ;

          if (i_index == first_length[i]) {
            FLG = false;
            break;
          }
        }
      }
      if (!FLG)
        break;
    }

    if (FLG) {
      second_length[words_index] = first_length[i];
      strcpy(words[words_index++], first_words[i]);
    } else {
      delete_num++;
    }
  }

  N -= delete_num;

  int common, tmp_common;

  for (int left = 0; left < N; left++) {
    for (int right = 0; right < N; right++) {
      if (left != right) {

        common = 0;

        for (int start = 0; start < second_length[left]; start++) {
          for (tmp_common = 0;
               tmp_common < second_length[right] &&
               start + tmp_common < second_length[left] &&
               words[left][start + tmp_common] == words[right][tmp_common];
               tmp_common++)
            ;

          if (start + tmp_common == second_length[left]) {
            common = tmp_common;
            break;
          }
        }

        match_len[left][right] = common;
      }
    }
  }

  queue<Info> Q;

  for (int i = 0; i < N; i++) {
    Info new_info;
    new_info.state = POW[i];
    new_info.num_used = 1;
    new_info.array[0] = i;
    new_info.total_length = second_length[i];
    Q.push(new_info);
  }

  int ans = BIG_NUM;

  char ans_word[101], tmp_word[101];

  while (!Q.empty()) {

    if (Q.front().num_used == N) {

      if (ans >= Q.front().total_length) {

        strcpy(tmp_word, words[Q.front().array[0]]);
        int index = second_length[Q.front().array[0]];

        int pre = Q.front().array[0];

        for (int i = 1; i < N; i++) {
          for (int k = match_len[pre][Q.front().array[i]];
               words[Q.front().array[i]][k] != '\\0'; k++) {
            tmp_word[index++] = words[Q.front().array[i]][k];
          }
          pre = Q.front().array[i];
        }

        tmp_word[Q.front().total_length] = '\\0';

        if (ans > Q.front().total_length) {
          ans = Q.front().total_length;
          strcpy(ans_word, tmp_word);
        } else {
          if (strCmp2(ans_word, tmp_word) == 2) {
            strcpy(ans_word, tmp_word);
          }
        }
      }
      Q.pop();
    } else if (Q.front().total_length >= ans) {
      Q.pop();
    } else {

      for (int i = 0; i < N; i++) {
        if (!(Q.front().state & (1 << i))) {
          Info new_info;
          for (int k = 0; k < Q.front().num_used; k++)
            new_info.array[k] = Q.front().array[k];
          new_info.state = Q.front().state + POW[i];
          new_info.num_used = Q.front().num_used + 1;
          new_info.array[Q.front().num_used] = i;
          new_info.total_length =
              Q.front().total_length + second_length[i] -
              match_len[Q.front().array[Q.front().num_used - 1]][i];
          Q.push(new_info);
        }
      }
      Q.pop();
    }
  }

  printf("%s\\n", ans_word);
}

int main() {

  for (int i = 0; i < 12; i++)
    POW[i] = pow(2, i);

  while (true) {
    scanf("%d", &N);
    if (N == 0)
      break;

    func();
  }

  return 0;
}