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

#include <algorithm>
#include <cfloat>
#include <cmath>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <string>
#include <time.h>
#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;

int POW[17];
int min_length[65536];
char num[2] = {'0', '1'}, var[4] = {'a', 'b', 'c', 'd'}, alloc_table[16][4];

struct Info {
  string tmp_str;
  int index;
};

int makeCode(int array[16]) {

  int ret = 0;

  for (int i = 0; i < 16; i++) {
    ret += array[i] * POW[i];
  }

  return ret;
}

int calc_two(char op, int a, int b) {

  if (op == '^') {

    return abs(a - b);

  } else { // op == '*'
    return a * b;
  }
}

int calc_equation(char buf[17], int left, int right) {

  int depth = 0, loc, max_depth = 0;
  char op = '@';

  for (int i = left; i <= right; i++) {
    if (buf[i] == '(') {
      depth++;
      max_depth = max(max_depth, depth);
    } else if (buf[i] == ')') {
      depth--;
    } else if (buf[i] == '^' || buf[i] == '*') {
      if (depth == 0) {
        op = buf[i];
        loc = i;
        break;
      }
    }
  }

  if (op == '@') {

    if (max_depth > 0) {

      if (buf[left] == '-') { //-<E>

        int minus_num = 0, loc = left;
        while (buf[loc] == '-') {
          minus_num++;
          loc++;
        }

        if (buf[loc] == '(') {
          if (minus_num % 2 == 0) {
            return calc_equation(buf, loc, right);
          } else {
            return 1 - calc_equation(buf, left + 1, right);
          }
        } else {

          if (minus_num % 2 == 0) {
            return buf[loc] - '0';
          } else {
            return 1 - (buf[loc] - '0');
          }
        }
      } else {
        return calc_equation(buf, left + 1, right - 1);
      }

    } else {

      int not_num = 0, tmp_index = left;

      while (buf[tmp_index] == '-') {
        not_num++;
        tmp_index++;
      }

      if (not_num % 2 == 0) {
        return buf[tmp_index] - '0';
      } else {

        return 1 - (buf[tmp_index] - '0');
      }
    }

  } else {

    int left_num = calc_equation(buf, left, loc - 1);
    int right_num = calc_equation(buf, loc + 1, right);

    return calc_two(op, left_num, right_num);
  }
}

int calc_all_pattern(char buf[17]) {

  int result[16];
  char tmp_buf[17];

  int length;
  for (length = 0; buf[length] != '\\0'; length++)
    ;

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

    for (int k = 0; k < length; k++) {
      if (buf[k] >= 'a' && buf[k] <= 'd') {
        tmp_buf[k] = alloc_table[i][buf[k] - 'a'];
      } else {
        tmp_buf[k] = buf[k];
      }
    }
    tmp_buf[length] = '\\0';

    result[i] = calc_equation(tmp_buf, 0, length - 1);
  }

  return makeCode(result);
}

void makeEquation() {

  vector<string> S;
  S.push_back("a");
  S.push_back("-a");
  S.push_back("b");
  S.push_back("-b");
  S.push_back("c");
  S.push_back("-c");
  S.push_back("d");
  S.push_back("-d");

  vector<string> WORK;

  for (int depth = 0; depth < 3; depth++) {
    WORK.clear();
    for (int i = 0; i < S.size(); i++) {
      for (int k = i; k < S.size(); k++) {
        if (S[i].size() + S[k].size() + 3 > 16)
          continue;

        string eq_1 = "(" + S[i] + "*" + S[k] + ")";
        string eq_2 = "(" + S[i] + "^" + S[k] + ")";

        WORK.push_back(eq_1);
        WORK.push_back(eq_2);

        if (eq_1.size() + 1 <= 16) {
          WORK.push_back("-" + eq_1);
        }
        if (eq_2.size() + 1 <= 16) {
          WORK.push_back("-" + eq_2);
        }
      }
    }
    for (int k = 0; k < WORK.size(); k++) {
      S.push_back(WORK[k]);
    }
  }

  S.push_back("0");
  S.push_back("1");

  int tmp_code;
  char buf[17];

  for (int i = 0; i < S.size(); i++) {

    for (int k = 0; k < S[i].size(); k++) {
      buf[k] = S[i][k];
    }
    buf[S[i].size()] = '\\0';

    tmp_code = calc_all_pattern(buf);

    min_length[tmp_code] = min(min_length[tmp_code], (int)S[i].size());
  }
}

void makeTable() {

  int index = 0;

  for (int a = 0; a < 2; a++) {
    for (int b = 0; b < 2; b++) {
      for (int c = 0; c < 2; c++) {
        for (int d = 0; d < 2; d++) {
          alloc_table[index][0] = '0' + a;
          alloc_table[index][1] = '0' + b;
          alloc_table[index][2] = '0' + c;
          alloc_table[index][3] = '0' + d;
          index++;
        }
      }
    }
  }
}

int main() {

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

  for (int i = 0; i < POW[16]; i++)
    min_length[i] = BIG_NUM;

  makeTable();
  makeEquation();

  char buf[17];

  while (true) {
    scanf("%s", buf);
    if (buf[0] == '.')
      break;

    printf("%d\\n", min_length[calc_all_pattern(buf)]);
  }

  return 0;
}


Error: TLE

Fixed submission:

#include <algorithm>
#include <cfloat>
#include <cmath>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <string>
#include <time.h>
#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;

int POW[17];
int min_length[65536];
char num[2] = {'0', '1'}, var[4] = {'a', 'b', 'c', 'd'}, alloc_table[16][4];

struct Info {
  string tmp_str;
  int index;
};

int makeCode(int array[16]) {

  int ret = 0;

  for (int i = 0; i < 16; i++) {
    ret += array[i] * POW[i];
  }

  return ret;
}

int calc_two(char op, int a, int b) {

  if (op == '^') {

    return abs(a - b);

  } else { // op == '*'
    return a * b;
  }
}

int calc_equation(char buf[17], int left, int right) {

  if (buf[left] == '-' && buf[left + 1] == '(') { //-<E>

    return 1 - calc_equation(buf, left + 1, right);
  }

  int depth = 0, loc, max_depth = 0;
  char op = '@';

  for (int i = left; i <= right; i++) {
    if (buf[i] == '(') {
      depth++;
      max_depth = max(max_depth, depth);
    } else if (buf[i] == ')') {
      depth--;
    } else if (buf[i] == '^' || buf[i] == '*') {
      if (depth == 0) {
        op = buf[i];
        loc = i;
        break;
      }
    }
  }

  if (op == '@') {

    if (max_depth > 0) {

      return calc_equation(buf, left + 1, right - 1);
    } else {

      int not_num = 0, tmp_index = left;

      while (buf[tmp_index] == '-') {
        not_num++;
        tmp_index++;
      }

      if (not_num % 2 == 0) {
        return buf[tmp_index] - '0';
      } else {
        return 1 - (buf[tmp_index] - '0');
      }
    }

  } else {

    int left_num = calc_equation(buf, left, loc - 1);
    int right_num = calc_equation(buf, loc + 1, right);

    return calc_two(op, left_num, right_num);
  }
}

int calc_all_pattern(char buf[17]) {

  int result[16];
  char tmp_buf[17];

  int length;
  for (length = 0; buf[length] != '\\0'; length++)
    ;

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

    for (int k = 0; k < length; k++) {
      if (buf[k] >= 'a' && buf[k] <= 'd') {
        tmp_buf[k] = alloc_table[i][buf[k] - 'a'];
      } else {
        tmp_buf[k] = buf[k];
      }
    }
    tmp_buf[length] = '\\0';

    result[i] = calc_equation(tmp_buf, 0, length - 1);
  }

  return makeCode(result);
}

/*
void recursive(string tmp_str,int index,int val_max){

        if(index >= tmp_str.size()){
                EQUATION.push_back(tmp_str);
                return;
        }

        int X_loc = -1;

        for(int i = index; i < tmp_str.size(); i++){
                if(tmp_str[i] == 'X'){
                        X_loc = i;
                        break;
                }
        }

        if(X_loc == -1){
                EQUATION.push_back(tmp_str);
                return;
        }

        for(int i = 0; i < min(val_max+1,4); i++){
                string next_str = tmp_str;
                next_str[X_loc] = var[i];
                recursive(next_str,X_loc+1,max(val_max,i+1));
        }
}
*/

void makeEquation() {

  vector<string> S;
  S.push_back("a");
  S.push_back("-a");
  S.push_back("b");
  S.push_back("-b");
  S.push_back("c");
  S.push_back("-c");
  S.push_back("d");
  S.push_back("-d");

  vector<string> WORK;

  for (int depth = 0; depth < 3; depth++) {
    WORK.clear();
    for (int i = 0; i < S.size(); i++) {
      for (int k = 0; k < S.size(); k++) {
        if (S[i].size() + S[k].size() + 3 > 16)
          continue;

        string eq_1 = "(" + S[i] + "*" + S[k] + ")";
        string eq_2 = "(" + S[i] + "^" + S[k] + ")";

        WORK.push_back(eq_1);
        WORK.push_back(eq_2);

        if (eq_1.size() + 1 <= 16) {
          WORK.push_back("-" + eq_1);
        }
        if (eq_2.size() + 1 <= 16) {
          WORK.push_back("-" + eq_2);
        }
      }
    }
    for (int k = 0; k < WORK.size(); k++) {
      S.push_back(WORK[k]);
    }
  }

  S.push_back("0");
  S.push_back("1");

  /*for(int i = 0; i < S.size(); i++){
          recursive(S[i],0,0);
  }*/

  int tmp_code;
  char buf[17];

  for (int i = 0; i < S.size(); i++) {

    for (int k = 0; k < S[i].size(); k++) {
      buf[k] = S[i][k];
    }
    buf[S[i].size()] = '\\0';

    tmp_code = calc_all_pattern(buf);
    min_length[tmp_code] = min(min_length[tmp_code], (int)S[i].size());
  }
}

void makeTable() {

  int index = 0;

  for (int a = 0; a < 2; a++) {
    for (int b = 0; b < 2; b++) {
      for (int c = 0; c < 2; c++) {
        for (int d = 0; d < 2; d++) {
          alloc_table[index][0] = '0' + a;
          alloc_table[index][1] = '0' + b;
          alloc_table[index][2] = '0' + c;
          alloc_table[index][3] = '0' + d;
          index++;
        }
      }
    }
  }
}

int main() {

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

  for (int i = 0; i < POW[16]; i++)
    min_length[i] = BIG_NUM;

  makeTable();
  makeEquation();

  char buf[17];

  int check[4], index, tmp;

  while (true) {
    scanf("%s", buf);
    if (buf[0] == '.')
      break;

    /*for(int i = 0; i < 4; i++)check[i] = -1;
    index = 0;

    for(int i = 0; buf[i] != '\\0'; i++){
            if(buf[i] >= 'a' && buf[i] <= 'd'){

                    tmp = buf[i]-'a';

                    if(check[tmp] == -1){
                            buf[i] = var[index];
                            check[tmp] = index;
                            index++;
                    }else{
                            buf[i] = var[check[tmp]];
                    }
            }
    }*/

    printf("%d\\n", min_length[calc_all_pattern(buf)]);
  }

  return 0;
}