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

#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <stdio.h>
#include <vector>

using namespace std;

struct Info {
  Info() {
    index = 0;
    for (int i = 0; i < 12; i++)
      check[i] = false;
  }

  short table[6], index;
  bool check[12];
};

void func(int M, int W) {
  int m_data[M], w_data[W];

  for (int i = 0; i < M; i++)
    scanf("%d", &m_data[i]);
  for (int i = 0; i < W; i++)
    scanf("%d", &w_data[i]);

  int maximum = 0, tmp, select_num, num, left_index, right_index, left_tmp,
      right_tmp, left_max, right_max, limit, loc_left[7], loc_right[7], val;

  if (M == 1) {
    for (int i = 0; i < W; i++) {
      tmp = abs(w_data[i] - m_data[0]) * (abs(w_data[i] - m_data[0]) - 30) *
            (abs(w_data[i] - m_data[0]) - 30);
      maximum = max(maximum, tmp);
    }
  } else if (W == 1) {
    for (int i = 0; i < M; i++) {
      tmp = abs(m_data[i] - w_data[0]) * (abs(m_data[i] - w_data[0]) - 30) *
            (abs(m_data[i] - w_data[0]) - 30);
      maximum = max(maximum, tmp);
    }
  } else {
    if (M > W) {
      select_num = (M + 1) / 2;

      limit = pow(2, M);
      for (int i = 0; i < limit; i++) {
        num = 0;
        for (int k = 0; k < M; k++) {
          if (i & (1 << k))
            num++;
        }
        if (num != select_num)
          continue;

        left_index = right_index = 0;

        //??°???????????????????????????
        for (int k = 0; k < M; k++) {
          if (i & (1 << k)) {
            loc_left[left_index++] = k;
          } else {
            loc_right[right_index++] = k;
          }
        }

        left_max = right_max = 0;

        queue<Info> Q;
        Info current, left_first, right_first;

        for (int k = 0; k < left_index; k++) {
          left_first.check[loc_left[k]] = true;
        }

        Q.push(left_first);

        while (!Q.empty()) {
          current = Q.front();
          Q.pop();

          if (current.index == left_index) {
            left_tmp = 0;
            for (int p = 0; p < (W + 1) / 2; p++) {
              val = abs(w_data[p] - current.table[p]);
              left_tmp += val * (val - 30) * (val - 30);
            }
            left_max = max(left_max, left_tmp);
            continue;
          }

          for (int p = 0; p < left_index; p++) {
            if (current.check[loc_left[p]]) {
              Info new_info;
              for (int k = 0; k < 12; k++)
                new_info.check[k] = current.check[k];
              for (int k = 0; k < current.index; k++)
                new_info.table[k] = current.table[k];
              new_info.table[current.index] = m_data[loc_left[p]];
              new_info.check[loc_left[p]] = false;
              new_info.index = current.index + 1;
              Q.push(new_info);
            }
          }
        }

        for (int k = 0; k < right_index; k++) {
          right_first.check[loc_right[k]] = true;
        }

        Q.push(right_first);

        while (!Q.empty()) {
          current = Q.front();
          Q.pop();

          if (current.index == right_index) {
            right_tmp = 0;
            for (int p = (W + 1) / 2; p < W; p++) {
              val = abs(w_data[p] - current.table[p - ((W + 1) / 2)]);
              right_tmp += val * (val - 30) * (val - 30);
            }
            right_max = max(right_max, right_tmp);
            continue;
          }

          for (int p = 0; p < right_index; p++) {
            if (current.check[loc_right[p]]) {
              Info new_info;
              for (int k = 0; k < 12; k++)
                new_info.check[k] = current.check[k];
              for (int k = 0; k < current.index; k++)
                new_info.table[k] = current.table[k];
              new_info.table[current.index] = m_data[loc_right[p]];
              new_info.check[loc_right[p]] = false;
              new_info.index = current.index + 1;
              Q.push(new_info);
            }
          }
        }

        maximum = max(maximum, left_max + right_max);
      }

    } else { // W >= M
      select_num = (W + 1) / 2;

      limit = pow(2, W);
      for (int i = 0; i < limit; i++) {
        num = 0;
        for (int k = 0; k < W; k++) {
          if (i & (1 << k))
            num++;
        }
        if (num != select_num)
          continue;

        left_index = right_index = 0;

        for (int k = 0; k < W; k++) {
          if (i & (1 << k)) {
            loc_left[left_index++] = k;
          } else {
            loc_right[right_index++] = k;
          }
        }

        left_max = right_max = 0;

        queue<Info> Q;
        Info current, left_first, right_first;

        for (int k = 0; k < left_index; k++) {
          left_first.check[loc_left[k]] = true;
        }

        Q.push(left_first);

        while (!Q.empty()) {
          current = Q.front();
          Q.pop();

          if (current.index == left_index) {
            left_tmp = 0;

            for (int p = 0; p < (M + 1) / 2; p++) {
              val = abs(m_data[p] - current.table[p]);
              left_tmp += val * (val - 30) * (val - 30);
            }
            left_max = max(left_max, left_tmp);
            continue;
          }

          for (int p = 0; p < left_index; p++) {
            if (current.check[loc_left[p]] == true) {
              Info new_info;
              for (int k = 0; k < W; k++)
                new_info.check[k] = current.check[k];
              for (int k = 0; k < current.index; k++)
                new_info.table[k] = current.table[k];
              new_info.table[current.index] = w_data[loc_left[p]];
              new_info.check[loc_left[p]] = false;
              new_info.index = current.index + 1;
              Q.push(new_info);
            }
          }
        }

        for (int k = 0; k < right_index; k++) {
          right_first.check[loc_right[k]] = true;
        }

        Q.push(right_first);

        while (!Q.empty()) {
          current = Q.front();
          Q.pop();

          if (current.index == right_index) {
            right_tmp = 0;
            for (int p = (M + 1) / 2; p < M; p++) {
              val = abs(m_data[p] - current.table[p - ((M + 1) / 2)]);
              right_tmp += val * (val - 30) * (val - 30);
            }
            right_max = max(right_max, right_tmp);
            continue;
          }

          for (int p = 0; p < right_index; p++) {
            if (current.check[loc_right[p]]) {
              Info new_info;
              for (int k = 0; k < W; k++)
                new_info.check[k] = current.check[k];
              for (int k = 0; k < current.index; k++)
                new_info.table[k] = current.table[k];
              new_info.table[current.index] = w_data[loc_right[p]];
              new_info.check[loc_right[p]] = false;
              new_info.index = current.index + 1;
              Q.push(new_info);
            }
          }
        }

        maximum = max(maximum, left_max + right_max);
      }
    }
  }
  printf("%d\\n", maximum);
}

int main() {

  int M, W;

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

    func(M, W);
  }

  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <stdio.h>
#include <vector>

using namespace std;

struct Info {
  Info() {
    index = 0;
    for (int i = 0; i < 12; i++)
      check[i] = false;
  }

  short table[6], index;
  bool check[12];
};

void func(int M, int W) {
  int m_data[M], w_data[W];

  for (int i = 0; i < M; i++)
    scanf("%d", &m_data[i]);
  for (int i = 0; i < W; i++)
    scanf("%d", &w_data[i]);

  int maximum = 0, tmp, select_num, num, left_index, right_index, left_tmp,
      right_tmp, left_max, right_max, limit, loc_left[7], loc_right[7], val;

  if (M == 1) {
    for (int i = 0; i < W; i++) {
      tmp = abs(w_data[i] - m_data[0]) * (abs(w_data[i] - m_data[0]) - 30) *
            (abs(w_data[i] - m_data[0]) - 30);
      maximum = max(maximum, tmp);
    }
  } else if (W == 1) {
    for (int i = 0; i < M; i++) {
      tmp = abs(m_data[i] - w_data[0]) * (abs(m_data[i] - w_data[0]) - 30) *
            (abs(m_data[i] - w_data[0]) - 30);
      maximum = max(maximum, tmp);
    }
  } else {
    if (M > W) {
      select_num = (M + 1) / 2;

      limit = pow(2, M);
      for (int i = 0; i < limit; i++) {
        num = 0;
        for (int k = 0; k < M; k++) {
          if (i & (1 << k))
            num++;
        }
        if (num != select_num)
          continue;

        left_index = right_index = 0;

        //??°???????????????????????????
        for (int k = 0; k < M; k++) {
          if (i & (1 << k)) {
            loc_left[left_index++] = k;
          } else {
            loc_right[right_index++] = k;
          }
        }

        left_max = right_max = 0;

        queue<Info> Q;
        Info current, left_first, right_first;

        for (int k = 0; k < left_index; k++) {
          left_first.check[loc_left[k]] = true;
        }

        Q.push(left_first);

        while (!Q.empty()) {
          current = Q.front();
          Q.pop();

          if (current.index == left_index) {
            left_tmp = 0;
            for (int p = 0; p < (W + 1) / 2; p++) {
              val = abs(w_data[p] - current.table[p]);
              left_tmp += val * (val - 30) * (val - 30);
            }
            left_max = max(left_max, left_tmp);
            continue;
          }

          for (int p = 0; p < M; p++) {
            if (current.check[p]) {
              Info new_info;
              for (int k = 0; k < M; k++)
                new_info.check[k] = current.check[k];
              for (int k = 0; k < current.index; k++)
                new_info.table[k] = current.table[k];
              new_info.table[current.index] = m_data[p];
              new_info.check[p] = false;
              new_info.index = current.index + 1;
              Q.push(new_info);
            }
          }
        }

        for (int k = 0; k < right_index; k++) {
          right_first.check[loc_right[k]] = true;
        }

        Q.push(right_first);

        while (!Q.empty()) {
          current = Q.front();
          Q.pop();

          if (current.index == right_index) {
            right_tmp = 0;
            for (int p = (W + 1) / 2; p < W; p++) {
              val = abs(w_data[p] - current.table[p - ((W + 1) / 2)]);
              right_tmp += val * (val - 30) * (val - 30);
            }
            right_max = max(right_max, right_tmp);
            continue;
          }

          for (int p = 0; p < M; p++) {
            if (current.check[p]) {
              Info new_info;
              for (int k = 0; k < M; k++)
                new_info.check[k] = current.check[k];
              for (int k = 0; k < current.index; k++)
                new_info.table[k] = current.table[k];
              new_info.table[current.index] = m_data[p];
              new_info.check[p] = false;
              new_info.index = current.index + 1;
              Q.push(new_info);
            }
          }
        }

        maximum = max(maximum, left_max + right_max);
      }

    } else { // W >= M
      select_num = (W + 1) / 2;

      limit = pow(2, W);
      for (int i = 0; i < limit; i++) {
        num = 0;
        for (int k = 0; k < W; k++) {
          if (i & (1 << k))
            num++;
        }
        if (num != select_num)
          continue;

        left_index = right_index = 0;

        for (int k = 0; k < W; k++) {
          if (i & (1 << k)) {
            loc_left[left_index++] = k;
          } else {
            loc_right[right_index++] = k;
          }
        }

        left_max = right_max = 0;

        queue<Info> Q;
        Info current, left_first, right_first;

        for (int k = 0; k < left_index; k++) {
          left_first.check[loc_left[k]] = true;
        }

        Q.push(left_first);

        while (!Q.empty()) {
          current = Q.front();
          Q.pop();

          if (current.index == left_index) {
            left_tmp = 0;

            for (int p = 0; p < (M + 1) / 2; p++) {
              val = abs(m_data[p] - current.table[p]);
              left_tmp += val * (val - 30) * (val - 30);
            }
            left_max = max(left_max, left_tmp);
            continue;
          }

          for (int p = 0; p < W; p++) {
            if (current.check[p] == true) {
              Info new_info;
              for (int k = 0; k < W; k++)
                new_info.check[k] = current.check[k];
              for (int k = 0; k < current.index; k++)
                new_info.table[k] = current.table[k];
              new_info.table[current.index] = w_data[p];
              new_info.check[p] = false;
              new_info.index = current.index + 1;
              Q.push(new_info);
            }
          }
        }

        for (int k = 0; k < right_index; k++) {
          right_first.check[loc_right[k]] = true;
        }

        Q.push(right_first);

        while (!Q.empty()) {
          current = Q.front();
          Q.pop();

          if (current.index == right_index) {
            right_tmp = 0;
            for (int p = (M + 1) / 2; p < M; p++) {
              val = abs(m_data[p] - current.table[p - ((M + 1) / 2)]);
              right_tmp += val * (val - 30) * (val - 30);
            }
            right_max = max(right_max, right_tmp);
            continue;
          }

          for (int p = 0; p < W; p++) {
            if (current.check[p]) {
              Info new_info;
              for (int k = 0; k < W; k++)
                new_info.check[k] = current.check[k];
              for (int k = 0; k < current.index; k++)
                new_info.table[k] = current.table[k];
              new_info.table[current.index] = w_data[p];
              new_info.check[p] = false;
              new_info.index = current.index + 1;
              Q.push(new_info);
            }
          }
        }

        maximum = max(maximum, left_max + right_max);
      }
    }
  }
  printf("%d\\n", maximum);
}

int main() {

  int M, W;

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

    func(M, W);
  }

  return 0;
}