Search code examples
c++matrixprimes

Find an element in a matrix M*M of numbers which have exactly 3 divisors in given time?


This was a task given on a coding competition a few months ago, and its still bugging me now. I did solve it, but my code did not give the result in required time for 3 test samples, likely due to the very large numbers they used. The thing is, looking at my code i see no obvious improvements that would reduce the time further.

The input has 3 numbers: the side length of the matrix, row and column of the required number. For a matrix size 3, it would look like:

4   9   16
121 49  25
169 289 361

A number that has 3 divisors can only be a squared prime number, so my solution was to generate primes until the needed position.

#include<iostream>
bool prime(long long a)
{
    //if(a%2==0) 
    //  return false; //no numbers passed will be even
    for(long long i=3;i*i<=a;i+=2)
        if(a%i==0) 
            return false;
    return true;
}
int main()
{
    int side, row, col, elem, count=1;
    long long num=1; 
    std::cin >> side >> row >> col;
    if(row==1 && col==1)
    {
        std::cout << '4';
        return 0;
    }
    elem=(row-1)*side+col+(row%2==0)*(side-2*col+1);//gets required position in matrix
    while(count<elem)
    {
        num+=2;
        if(prime(num)) 
            count++;
    }
    std::cout << num*num;
}

Solution

  • Rather than this:

    while(count<elem)
    {
        num+=2;
        if(prime(num)) 
            count++;
    }
    

    This:

    vector<long long> primes;
    primes.push_back(2);
    
    while (count < elem)
    {
        num += 2;
        if (prime(num, primes)) {
           primes.push_back(num);
           count++;
        }
    } 
    

    Where your prime function is modified to only test divisibility against previously found prime numbers:

    bool prime(long long num, const vector<long long>& primes)
    {
       for (auto p : primes)
       {
           if (num % p == 0)
           {
              return false;
           }
       }
       return true;
    }
    

    The above should speed things up significantly. There's also the sieve of eros thing. But the above should be sufficient for most leet coding challenge sites.