Problem p00776 (C++) — buggy submission, verdict: Time Limit Exceeded

#include "bits/stdc++.h"
using namespace std;

// motoを暗号化規則によって暗号化する
string crypt(string moto, int n) {
  bool f[26] = {};
  f[0] = true;
  int p;
  for (int i = 0; i < n; ++i) {
    p = moto[i] - 'a';
    if (!f[p]) {
      f[p] = true;
      --moto[i];
    }
  }
  return moto;
}
string a[1 << 22];
string s;
string t;
int ans;
void saiki(string tmp, int i, int n) {
  if (i == n) {
    if (crypt(tmp, n) == s) {
      a[ans] = tmp;
      ans++;
    }
    return;
  }
  if (tmp[i] != 'z') {
    saiki(tmp, i + 1, n);
    tmp[i]++;
    saiki(tmp, i + 1, n);
  } else {
    saiki(tmp, i + 1, n);
  }
  return;
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  bool f;
  int n;
  int i;
  int bit;
  while (1) {
    ans = 0;
    cin >> s;
    n = s.size();
    if (s[0] == '#')
      break;
    saiki(s, 0, n);
    cout << ans << endl;
    if (ans > 10) {
      for (i = 0; i < 5; i++)
        cout << a[i] << endl;
      for (i = ans - 5; i < ans; i++)
        cout << a[i] << endl;
    } else {
      for (i = 0; i < ans; i++)
        cout << a[i] << endl;
    }
  }
  return 0;
}


Error: TLE

Fixed submission:

#include "bits/stdc++.h"
using namespace std;

// motoを暗号化規則によって暗号化する
string crypt(string moto, int &n) {
  bool f[26] = {};
  f[0] = true;
  int p;
  for (int i = 0; i < n; ++i) {
    p = moto[i] - 'a';
    if (!f[p]) {
      f[p] = true;
      --moto[i];
    }
  }
  return moto;
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  vector<string> a;
  string s;
  string t;
  bool f;
  int ans;
  int n;
  while (1) {
    ans = 0;
    cin >> s;
    n = s.size();
    if (s[0] == '#')
      break;
    // すべての文字が変化しているかしていないかで全探索
    // 1なら変化
    a.clear();
    int l = 0; // 書き換えないものが多いほど辞書順で前に来る
    int r = (1 << n) - 1; // 書き換えるものが多いほど辞書順で後ろに来る
    // 前から見る
    for (int bit = l; bit < (1 << n); ++bit) {
      t = s;
      f = true;
      for (int i = 0; i < n; ++i) {
        if (bit & (1 << i)) {
          if (t[i] == 'z') {
            f = false;
            break; // zは変化しない
          }
          ++t[i];
        }
      }
      if (!f)
        continue;
      if (crypt(t, n) == s) {
        a.push_back(t);
        ans++;
      }
      if (ans == 5) {
        l = bit;
        break;
      }
    }
    ans = 0;
    // 後ろから見る
    for (int bit = r; bit >= 0; --bit) {
      t = s;
      f = true;
      for (int i = 0; i < n; ++i) {
        if (bit & (1 << i)) {
          if (t[i] == 'z') {
            f = false;
            break; // zは変化しない
          }
          ++t[i];
        }
      }
      if (!f)
        continue;
      if (crypt(t, n) == s) {
        a.push_back(t);
        ans++;
      }
      if (ans == 5) {
        r = bit;
        break;
      }
    }
    sort(a.begin(), a.end());
    a.erase(unique(a.begin(), a.end()), a.end()); // ここで重複を取っておく
    ans = a.size();
    // 残りを見る
    for (int bit = l + 1; bit < r; ++bit) {
      t = s;
      f = true;
      for (int i = 0; i < n; ++i) {
        if (bit & (1 << i)) {
          if (t[i] == 'z') {
            f = false;
            break; // zは変化しない
          }
          ++t[i];
        }
      }
      if (!f)
        continue;
      if (crypt(t, n) == s)
        ans++;
    }
    printf("%d\\n", ans);

    for (int i = 0; i < a.size(); ++i)
      printf("%s\\n", a[i].c_str());
  }
  return 0;
}