Problem p01228 (C++) — buggy submission, verdict: Runtime Error

#include <algorithm>
#include <cassert>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>
using namespace std;

#define rep(i, n) for (int(i) = 0; (i) < (int)(n); ++(i))
#define foreach(c, i)                                                          \\
  for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); i++)

int gcd(int a, int b) {
  if (b == 0)
    return a;
  return gcd(b, a % b);
}

int c2i(const char c) { return c - '0'; }

int s0x2i(const string &s) { return c2i(s[0]) * 16 + c2i(s[1]); }

vector<char> conv;

int N;
vector<string> vs;
const string zero = "00";

void solve() {
  vector<int> denoms;
  rep(i, N) {
    const int baseDenom = vs[i].size() / 2;
    for (int j = 0; j < vs[i].size(); j += 2) {
      string sub = vs[i].substr(j, 2);
      if (sub == zero)
        continue;
      int num = j / 2;
      int denom = baseDenom / gcd(baseDenom, num);

      // if (baseDenom == 880 && num == 776) {
      //   printf("especially !! denom->%d\\n", denom);
      // }

      denoms.push_back(denom);
    }
  }

  sort(denoms.begin(), denoms.end());
  denoms.erase(unique(denoms.begin(), denoms.end()), denoms.end());
  // rep(i,denoms.size()) {printf("[%d]", denoms[i]);} puts("");

  map<int, int> m;
  rep(i, denoms.size()) {
    int num = denoms[i];
    for (int j = 2; j * j <= num; ++j) {
      int cnt = 0;
      while (num % j == 0) {
        ++cnt;
        num /= j;
      }
      if (cnt) {
        m[j] = max(m[j], cnt);
      }
    }
    if (num > 1 && m.count(num) == 0)
      m[num] = 1;
  }

  // foreach(m, itr) { printf("[%d:%d]", itr->first, itr->second); } puts("");

  int finalDenom = 1;
  foreach (m, itr) {
    finalDenom *= pow(itr->first, itr->second);
    if (finalDenom > (2048) / 2)
      break;
  }

  // printf("finalDenom::%d\\n", finalDenom);
  if (finalDenom > (2048 / 2)) {
    cout << "Too complex." << endl;
    return;
  }

  vector<int> resInt(finalDenom, 0);
  rep(i, N) {
    const int baseDenom = vs[i].size() / 2;
    for (int j = 0; j < vs[i].size(); j += 2) {
      string sub = vs[i].substr(j, 2);
      int num = s0x2i(sub); // index = (j/2) / gcd(baseDenom, j/2);
      if (num == 0)
        continue;
      const int kgcd = gcd(baseDenom, j / 2);
      int index = (j / 2) / kgcd;

      if (finalDenom > (baseDenom / kgcd)) {
        index *= finalDenom / (baseDenom / kgcd);
        // index = (j / 2) * (finalDenom / gcd(baseDenom, j/2));
      } else {
        index /= (baseDenom / kgcd) / finalDenom;
        // index = (j / 2) / (gcd(baseDenom, j/2) / finalDenom);
      }
      if (index >= finalDenom) {
        // printf("index:finalDenom -- %d:%d\\n", index, finalDenom);
        // printf("j:vs[i].size() -- %d:%d\\n", j, vs[i].size());
        // printf("num -- %d\\n", num);
      }
      assert(index < finalDenom);
      resInt[index] += num;
    }
  }

  rep(i, resInt.size()) {
    int num = resInt[i];
    if (num > 255) {
      printf("num assert :: %d\\n", num);
    }
    assert(num <= 255);
    cout << conv[num / 16] << conv[num % 16];
  }
  cout << endl;
}

void input() {
  // vs clear
  vs.clear();

  cin >> N;
  cin.ignore();
  string s;
  rep(i, N) {
    getline(cin, s);
    vs.push_back(s);
  }
}

int main() {
  // cout << "gcd(1760, 1552) = " << gcd(1760, 1552) << endl;
  rep(i, 10) { conv.push_back('0' + i); }
  rep(i, 6) { conv.push_back('A' + i); }
  int T;
  cin >> T;
  int cT = T;
  while (T--) {
    // cout << "Case #" << cT - T << endl;
    input();
    solve();
  }
  return 0;
}

Error: 0

Fixed submission:

#include <algorithm>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>
using namespace std;

#define rep(i, n) for (int(i) = 0; (i) < (int)(n); ++(i))
#define foreach(c, i)                                                          \\
  for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); i++)

int gcd(int a, int b) {
  if (b == 0)
    return a;
  return gcd(b, a % b);
}

int c2i(const char c) { return c - '0'; }

int s0x2i(const string &s) { return c2i(s[0]) * 16 + c2i(s[1]); }

vector<char> conv;

int N;
vector<string> vs;
const string zero = "00";

void solve() {
  vector<int> maxDenom;
  rep(i, N) {
    const int baseDenom = vs[i].size() / 2;
    int mxDenom = -1;
    for (int j = 0; j < vs[i].size(); j += 2) {
      string sub = vs[i].substr(j, 2);
      if (sub == zero)
        continue;
      int num = j / 2;
      int denom = baseDenom / gcd(num, baseDenom);
      if (denom > mxDenom)
        mxDenom = denom;
    }
    if (mxDenom != -1)
      maxDenom.push_back(mxDenom);
  }

  // rep(i,maxDenom.size()) printf("{%d}", maxDenom[i]); puts("");

  map<int, int> m;
  rep(i, maxDenom.size()) {
    int num = maxDenom[i];
    for (int j = 2; j * j <= num; ++j) {
      int cnt = 0;
      while (num % j == 0) {
        ++cnt;
        num /= j;
      }
      if (cnt) {
        m[j] = max(m[j], cnt);
      }
    }
    if (num > 1 && m.count(num) == 0)
      m[num] = 1;
  }

  // foreach(m, itr) { printf("[%d:%d]", itr->first, itr->second); } puts("");

  int finalDenom = 1;
  foreach (m, itr) {
    finalDenom *= pow(itr->first, itr->second);
  }
  // printf("finalDenom::%d\\n", finalDenom);
  if (finalDenom > (2048 / 2)) {
    cout << "Too complex." << endl;
    return;
  }

  vector<int> resInt(finalDenom, 0);
  rep(i, N) {
    const int baseDenom = vs[i].size() / 2;
    for (int j = 0; j < vs[i].size(); j += 2) {
      string sub = vs[i].substr(j, 2);
      int num = s0x2i(sub);
      if (finalDenom > baseDenom) {
        int index = (j / 2) * (finalDenom / baseDenom);
        resInt[index] += num;
      } else {
        int index = (j / 2) / (baseDenom / finalDenom);
        resInt[index] += num;
      }
    }
  }

  rep(i, resInt.size()) {
    int num = resInt[i];
    cout << conv[num / 16] << conv[num % 16];
  }
  cout << endl;
}

void input() {
  // vs clear
  vs.clear();

  cin >> N;
  cin.ignore();
  string s;
  rep(i, N) {
    getline(cin, s);
    vs.push_back(s);
  }
}

int main() {
  ios_base::sync_with_stdio(false);

  rep(i, 10) { conv.push_back('0' + i); }
  rep(i, 6) { conv.push_back('A' + i); }

  int T;
  cin >> T;
  while (T--) {
    input();
    solve();
  }
  return 0;
}