-3

I'm getting Segmentation error for the code below. This is a solution to the SPOJ problem "Coins".

I went through How to avoid SIGSEGV? and I made sure not to use uninitialized pointers, not to access out of memory etc (given n ≤ 109).

I know that an array a[1000000000] would lead to stack overflow, so I used std::map. Will a std::map ever lead to a stack overflow? What is wrong with my code?

#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <map>

using namespace std;

map<unsigned long long int, unsigned long long int> a;

unsigned long long int dp(unsigned long long int n)
{   
   if (a.find(n) == a.end())
      a[n] = dp(n/2) + dp(n/3) + dp(n/4);

   return a[n];
}

int main()
{
    for (unsigned long long int i = 1; i <= 24; i++) {
        a[i] = i;
        if (i == 12 || i == 24)
           a[i] = i + 1;
    }

    unsigned long long int n = 0;
    cin >> n;

    while (!feof(stdin)) {
        printf("%llu\n", dp(n));
        cin >> n;
    }
}
Community
  • 1
  • 1
rsd_unleashed
  • 151
  • 2
  • 12

1 Answers1

1

You get SIGSEGV on dp(0) call. It causes an infinite recursion.

By the way, your solution is wrong, for example the answer for 24 is not 25. Try to avoid magic constants, it is just enough to set a[0] = 0 and make a more accurate dp function:

uint32_t dp(uint32_t n) {
    if (a.find(n) == a.end())
        a[n] = max(n, dp(n / 2) + dp(n / 3) + dp(n / 4));

    return a[n];
}

As can be seen above, 32-bit type is enough to store any possible answer.

iskhakovt
  • 458
  • 4
  • 13