mercredi 8 juillet 2020

Usaco Section 1.6 Prime Palindromes

Hello so I was doing this problem in which they give you a range from a minimum of 5 to a maximum of 100,000,000

and you have to find all prime palindromes from the first number to the second number

example:

input: 5 500

output:

5

7

11

101

131

151

181

191

313

353

373

383

So before you look at my solution you need to understand 2 things that all prime numbers except for some of the first ones end with this 4 digits 1,3,7,9 and that all palindromes with an even number of digits are divisible by 11

so understanding this you know that all prime palindromes need to start with one of these 4 digits and that there are no prime palindromes with an even number of digits example: 7557

so my solution was to create palindromes and check if they are prime and then print them and the way I used to check them was by having a number like 12 and then reversing it and appending it like 1221 and adding a number in the center from 1 to 9: 12121

but the way I did it was so that all numbers started with this 4 digits in this way:

from 1-1 3-3 7-7 9-9

 10-19 30-39 70-79 90 99

and I did this until the numbers produced were larger than the limit in which case I stopped creating new palindromes and the good thing about this is that I get them in order

creating my solution:

 #include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef vector < long long > vi;
typedef pair < long long, long long > pi;
typedef vector < pi > vpi;


ifstream fin("pprime.in");
ofstream fout("pprime.out");

int reverse2(int num, int middle) {
  int i, save = num, digit, combino = 1;
  for (i = 0; num; num /= 10) {
    digit = num % 10;
    i = 10 * i + digit;
    combino *= 10;
  }
  return i + 10 * combino * save + combino * middle;
}


bool prime(int n) {

  if (n <= 1)
    return false;

  for (int i = 2; i < n; i++)
    if (n % i == 0)
      return false;

  return true;
}

bool solve(int i, int n, int m, int digits) {

  int c, b;
  c = reverse2(i, 0);

  for (int j = 0; j <= 9; j++) {

    b = c + j * digits;
    
    if (b >= n && b <= m) {
      if (prime(b)) {
        fout << b << endl;
      }
    }
    if (b > m) {
      return 0;
    }

  }

  return 1;
}

int main() {

  int n, m;
  fin >> n >> m;

  if (5 >= n && 5 <= m) {
    fout << 5 << endl;
  }
  if (7 >= n && 7 <= m) {
    fout << 7 << endl;
  }
  if (11 >= n && 11 <= m) {
    fout << 11 << endl;
  }
  int arr[4] = { 1,3,7,9};

  bool b = 0;
int digits = 10;

  while (!b) {

    for (int j = 0; j < 4; j++) {
      int s = arr[j];
      int actualdigit = arr[j] * digits / 10;

      for (int i = actualdigit; i < (actualdigit/ s) * (s + 1); i++) {

        bool a = solve(i, n, m, digits);
        if (!a) {
          b = 1;
          j = 20;
          break;
        }

      }
    }

    digits *= 10;
  }

  return 0;
}

The problem here is that my solution runs out of time for example in this case: 9878210 9978210

even though the reverse function I used was gotten from another solution which also solves the problem

other guy's code:

#include <iostream.h>
#include <fstream.h>
#include <stdlib.h>

int primelist[100000];
int nprimes;

int isPrime(int num);
int reverse2(int i, int j);

int compare(const void *p, const void *q) { return *(int *)p-*(int *)q; }

void main (void) {
    ifstream infile("pprime.in");
    ofstream outfile("pprime.out"); 
    int i, j, begin, end, num;
    infile>>begin>>end;
    if (begin <= 11 && 11 <=end)
        primelist[nprimes++] = 11;
    for (j = 0; j <= 999; j++)
        for (i = 0; i <= 9; i++)  {
        num = reverse2(j,i);
        if (num >= begin && num <=end && isPrime(num)) 
            primelist[nprimes++] = num;
        }
    qsort(primelist, nprimes, sizeof(int), compare);
    for (i = 0; i < nprimes; i++)
    outfile << primelist[i] << "\n";
}

int
reverse2(int num, int middle) {
    int i, save=num, digit, combino = 1;
    for (i = 0; num; num /= 10) {
    digit = num % 10;
    i = 10 * i + digit;
    combino *= 10;
    }
    return i+10*combino*save+combino*middle;
}
    
int isPrime(int num) {
    int i;
    if (num <= 3) return 1;
    if (num%2 == 0 || num%3 ==0) return 0;
    for (i = 5; i*i <= num; i++)
    if (num %i ==0)
        return 0;
    return 1;
}

so the question is why does my program run out of time and his doesn't if both do the same thing but I do the procedure in fewer cases than him?

Aucun commentaire:

Enregistrer un commentaire