Problem p03593 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
int num[30], hehe[5], color[111][111];
int h, w;
char s[1001];
bool dfs(int x, int y) {
  if (x == h + 1)
    return true;
  if (color[x][y]) {
    if (y == w)
      return dfs(x + 1, 1);
    else
      return dfs(x, y + 1);
  }
  for (int c = 1; c <= 27; c++)
    if (num[c]) {
      int i, j, cnt = 1;
      color[x][y] = c;
      i = h - x + 1, j = w - y + 1;
      if (!color[i][j]) {
        cnt++;
        color[i][j] = c;
      }
      i = x, j = w - y + 1;
      if (!color[i][j]) {
        cnt++;
        color[i][j] = c;
      }
      i = h - x + 1, j = y;
      if (!color[i][j]) {
        cnt++;
        color[i][j] = c;
      }
      if (num[c] >= cnt) {
        num[c] -= cnt;
        bool could;
        if (y == w)
          could = dfs(x + 1, 1);
        else
          could = dfs(x, y + 1);
        if (could)
          return could;
        num[c] += cnt;
      }
      color[x][y] = 0;
      i = h - x + 1, j = w - y + 1;
      color[i][j] = 0;
      i = x, j = w - y + 1;
      color[i][j] = 0;
      i = h - x + 1, j = y;
      color[i][j] = 0;
    }
  return false;
}
int main() {
  scanf("%d%d", &h, &w);
  for (int i = 1; i <= h; i++) {
    scanf("%s", s);
    for (int j = 0; j < w; j++)
      num[s[j] - 'a' + 1]++;
  }
  if (w == 1 || h == 1) {
    if (dfs(1, 1))
      printf("Yes\n");
    else
      printf("No\n");
    return 0;
  }
  if ((w & 1) && (h & 1)) {
    hehe[1] = 1;
    hehe[2] = (w - 1) / 2 + (h - 1) / 2;
    hehe[4] = (h * w - 1 - hehe[2] * 2) / 4;
    for (int i = 1; i <= 27; i++) {
      if (num[i]) {
        if (num[i] & 1) {
          if (!hehe[1]) {
            printf("No\n");
            return 0;
          }
          hehe[1] = 0;
          num[i]--;
        }
        if (hehe[4] >= num[i] / 4) {
          hehe[4] -= num[i] / 4;
          num[i] %= 4;
        }
        if (hehe[2] >= num[i] / 2) {
          hehe[2] -= num[i] / 2;
          num[i] %= 2;
        }
      }
    }
    for (int i = 1; i <= 27; i++)
      if (num[i]) {
        printf("No\n");
        return 0;
      }
    printf("Yes\n");
    return 0;
  } else {
    if (!(w & 1) && !(h & 1)) {
      hehe[4] = w * h / 4;
      for (int i = 1; i <= 27; i++)
        if (num[i]) {
          hehe[4] -= num[i] / 4;
          num[i] %= 4;
        }
      for (int i = 1; i <= 27; i++)
        if (num[i]) {
          printf("No\n");
          return 0;
        }
      printf("Yes\n");
      return 0;
    }
    if (w & 1) {
      hehe[2] = h / 2;
      hehe[4] = (w * h - h) / 4;
      for (int i = 1; i <= 27; i++) {
        if (num[i]) {
          if (hehe[4] >= num[i] / 4) {
            hehe[4] -= num[i] / 4;
            num[i] %= 4;
          }
          if (hehe[2] >= num[i] / 2) {
            hehe[2] -= num[i] / 2;
            num[i] %= 2;
          }
        }
      }
      for (int i = 1; i <= 27; i++)
        if (num[i]) {
          printf("No\n");
          return 0;
        }
      printf("Yes\n");
      return 0;
    } else {
      hehe[2] = w / 2;
      hehe[4] = (w * h - w) / 4;
      for (int i = 1; i <= 27; i++) {
        if (num[i]) {
          if (hehe[4] >= num[i] / 4) {
            hehe[4] -= num[i] / 4;
            num[i] %= 4;
          }
          if (hehe[2] >= num[i] / 2) {
            hehe[2] -= num[i] / 2;
            num[i] %= 2;
          }
        }
      }
      for (int i = 1; i <= 27; i++)
        if (num[i]) {
          printf("No\n");
          return 0;
        }
      printf("Yes\n");
      return 0;
    }
  }
}

Fixed submission:
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
int num[30], hehe[5], color[111][111];
int h, w;
char s[1001];
bool dfs(int x, int y) {
  if (x == h + 1)
    return true;
  if (color[x][y]) {
    if (y == w)
      return dfs(x + 1, 1);
    else
      return dfs(x, y + 1);
  }
  for (int c = 1; c <= 27; c++)
    if (num[c]) {
      int i, j, cnt = 1;
      color[x][y] = c;
      i = h - x + 1, j = w - y + 1;
      if (!color[i][j]) {
        cnt++;
        color[i][j] = c;
      }
      i = x, j = w - y + 1;
      if (!color[i][j]) {
        cnt++;
        color[i][j] = c;
      }
      i = h - x + 1, j = y;
      if (!color[i][j]) {
        cnt++;
        color[i][j] = c;
      }
      if (num[c] >= cnt) {
        num[c] -= cnt;
        bool could;
        if (y == w)
          could = dfs(x + 1, 1);
        else
          could = dfs(x, y + 1);
        if (could)
          return could;
        num[c] += cnt;
      }
      color[x][y] = 0;
      i = h - x + 1, j = w - y + 1;
      color[i][j] = 0;
      i = x, j = w - y + 1;
      color[i][j] = 0;
      i = h - x + 1, j = y;
      color[i][j] = 0;
    }
  return false;
}
int main() {
  scanf("%d%d", &h, &w);
  for (int i = 1; i <= h; i++) {
    scanf("%s", s);
    for (int j = 0; j < w; j++)
      num[s[j] - 'a' + 1]++;
  }
  if ((w & 1) && (h & 1)) {
    hehe[1] = 1;
    hehe[2] = (w - 1) / 2 + (h - 1) / 2;
    hehe[4] = (h * w - 1 - hehe[2] * 2) / 4;
    for (int i = 1; i <= 27; i++) {
      if (num[i]) {
        if (num[i] & 1) {
          if (!hehe[1]) {
            printf("No\n");
            return 0;
          }
          hehe[1] = 0;
          num[i]--;
        }
        if (hehe[4] >= num[i] / 4) {
          hehe[4] -= num[i] / 4;
          num[i] %= 4;
        }
        if (hehe[2] >= num[i] / 2) {
          hehe[2] -= num[i] / 2;
          num[i] %= 2;
        }
      }
    }
    for (int i = 1; i <= 27; i++)
      if (num[i]) {
        printf("No\n");
        return 0;
      }
    printf("Yes\n");
    return 0;
  } else {
    if (!(w & 1) && !(h & 1)) {
      hehe[4] = w * h / 4;
      for (int i = 1; i <= 27; i++)
        if (num[i]) {
          hehe[4] -= num[i] / 4;
          num[i] %= 4;
        }
      for (int i = 1; i <= 27; i++)
        if (num[i]) {
          printf("No\n");
          return 0;
        }
      printf("Yes\n");
      return 0;
    }
    if (w & 1) {
      hehe[2] = h / 2;
      hehe[4] = (w * h - h) / 4;
      for (int i = 1; i <= 27; i++) {
        if (num[i]) {
          if (hehe[4] >= num[i] / 4) {
            hehe[4] -= num[i] / 4;
            num[i] %= 4;
          }
          if (hehe[2] >= num[i] / 2) {
            hehe[2] -= num[i] / 2;
            num[i] %= 2;
          }
        }
      }
      for (int i = 1; i <= 27; i++)
        if (num[i]) {
          printf("No\n");
          return 0;
        }
      printf("Yes\n");
      return 0;
    } else {
      hehe[2] = w / 2;
      hehe[4] = (w * h - w) / 4;
      for (int i = 1; i <= 27; i++) {
        if (num[i]) {
          if (hehe[4] >= num[i] / 4) {
            hehe[4] -= num[i] / 4;
            num[i] %= 4;
          }
          if (hehe[2] >= num[i] / 2) {
            hehe[2] -= num[i] / 2;
            num[i] %= 2;
          }
        }
      }
      for (int i = 1; i <= 27; i++)
        if (num[i]) {
          printf("No\n");
          return 0;
        }
      printf("Yes\n");
      return 0;
    }
  }
}