-2

The question is:

Ramanujan is so fond of playing number games. One day Ramanujan and Anish played a game. Ramanujan gave Anish a number string and asked him to find all the distinct substrings of size at most six that are prime. Anish being good at maths takes up the game and if he can give solutions to all the input sets Ramanujan provides him, Anish wins the game. Your task is to help Anish win the game.

Input Format

First line contains T, The number of test cases. Each test case contains a string of size N containing only integers.

Constraints

1 <= Number of Test Cases <= 10 1 <= N <= 10^7

Output Format

For Each Test case, print the total number of distinct prime substrings of length at most 6.

My code is in c++: I had created a vector and map of all the prime number which is less than square root of 10^7 and had intialised map with 1(1 indicates prime number,0 indicates composite number). Even for checking whether the number is prime or not ,I am dividing it with only prime number less than its square root. But even doing all this ,I am unable to pass 2nd testcase(showing terminated due to timeout).I am only able to pass 1st test case.I think my program is taking a lot of time to create substrings(using substr() function).Is there any way to reduce time complexity ?plz answer.

map<long int,int>mp{{2,1},{3,1},{5,1},............................,{3121,1},{3137,1}};


map<long int,int>p;

vector<long int>v{2,3,5,..............3137};

 long int c=0;


void check_prime(long int n)

{
    long int i;



     int flag=-1;

        for(i=0;v[i]*v[i]<=n;i++)
        {

            if(n%v[i]==0)
            {
                flag=1;
                break;
            }

        }
        if(flag==-1)
        {
            ++c;
            mp.insert(pair<long int,int>(n,1));


            p.insert(pair<long int,int>(n,1));


        }
        else
        {
            mp.insert(pair<long int,int>(n,0));
            p.insert(pair<long int,int>(n,1));
        }




}
int main() {


    int t;
    string s;
    long int  n,n1,i,j;

    cin>>t;
    while(t--)
    {
        long int i,j;

        cin>>s;


        for(i=0;i<s.length();i++)
        {
             int l=s.length()-i;

            for(j=1;j<=min(6,l);j++)
            {
                n=stoi(s.substr(i,j));



              if(p.count(n)==0)  
              {
                if(mp.count(n)==1 )
                {
                    if(mp[n]==1 )
                    {
                        ++c;
                        p.insert(pair<long int,int>(n,1));

                    }
                    else
                    {
                         p.insert(pair<long int,int>(n,1));
                    }
                }
                else
                {
                   if(n<3162 || n%2==0 || n%5==0)
                   {
                       mp.insert(pair<long int,int>(n,0));
                       p.insert(pair<long int,int>(n,1));
                   }

                    else
                    {

                       check_prime(n);
                    }

                }
              }
            }
        }
        cout<<c<<endl;
        p.clear();
        c=0;
    }
    return 0;
}
Ga25
  • 1
  • 1

1 Answers1

0

You don't need call check_prime() every time in the loop.

Instead, call it once to save result and use it later on.

Consider Sieve of Eratosthenes:

int np[1000000];  // not prime
int main(void)
{
    np[1] = 1;
    for (int i = 2; i*i < 1000000; i++)
        for (int j = 2; i*j < 1000000; j++)
            np[i*j] = 1;

    // use np[n].
    return 0;
}

Using np[n] will take O(1) as oppose to O(sqrt(n)) before.

CodingLab
  • 1,441
  • 2
  • 13
  • 37