[Codility] CommonPrimeDivisors

prime is a positive integer X that has exactly two distinct divisors: 1 and X. The first few prime integers are 2, 3, 5, 7, 11 and 13.

A prime D is called a prime divisor of a positive integer P if there exists a positive integer K such that D * K = P. For example, 2 and 5 are prime divisors of 20.

You are given two positive integers N and M. The goal is to check whether the sets of prime divisors of integers N and M are exactly the same.

For example, given:

  • N = 15 and M = 75, the prime divisors are the same: {3, 5};
  • N = 10 and M = 30, the prime divisors aren't the same: {2, 5} is not equal to {2, 3, 5};
  • N = 9 and M = 5, the prime divisors aren't the same: {3} is not equal to {5}.

Write a function:

int solution(vector<int> &A, vector<int> &B);

that, given two non-empty zero-indexed arrays A and B of Z integers, returns the number of positions K for which the prime divisors of A[K] and B[K] are exactly the same.

For example, given:

    A[0] = 15   B[0] = 75

    A[1] = 10   B[1] = 30

    A[2] = 3    B[2] = 5

the function should return 1, because only one pair (15, 75) has the same set of prime divisors.

Assume that:

  • Z is an integer within the range [1..6,000];
  • each element of arrays A, B is an integer within the range [1..2,147,483,647].

Complexity:

  • expected worst-case time complexity is O(Z*log(max(A)+max(B))2);
  • expected worst-case space complexity is O(1), beyond input storage (not counting the storage required for input arguments).

判断两个数是否有相同的素数约数。首先求出公约数gcd_val,那么gcd_val里应该包含了common prime divisor,下面分别判断a跟b与gcd_val的公约数是不是有自己的非common prime divisor的prime divisor。

 1 // you can use includes, for example:

 2 // #include <algorithm>

 3 

 4 // you can write to stdout for debugging purposes, e.g.

 5 // cout << "this is a debug message" << endl;

 6 int gcd(int a, int b) {

 7     if (a < b) return gcd(b, a);

 8     return b > 0 ? gcd(b, a % b) : a;

 9 }

10 

11 bool hasSamePrimeDivisors(int a, int b) {

12     int gcd_val = gcd(a, b);

13     int gcd_a, gcd_b;

14     while (a != 1) {

15         gcd_a = gcd(a, gcd_val);

16         if (gcd_a == 1) break;

17         a /= gcd_a;

18     }

19     if (a != 1) return false;

20     while (b != 1) {

21         gcd_b = gcd(b, gcd_val);

22         if (gcd_b == 1) break;

23         b /= gcd_b;

24     }

25     return b == 1;

26 }

27 

28 int solution(vector<int> &A, vector<int> &B) {

29     // write your code in C++11

30     int cnt = 0;

31     for (int i = 0; i < A.size() && i < B.size(); ++i) {

32         if (hasSamePrimeDivisors(A[i], B[i])) ++cnt;

33     }

34     return cnt;

35 }
 1 def gcd(x, y):

 2     # Compute the greatest common divisor

 3     if x%y == 0:

 4         return y;

 5     else:

 6         return gcd(y, x%y)

 7 

 8 def hasSamePrimeDivisors(x, y):

 9     gcd_value = gcd(x, y)   # The gcd contains all

10                             # the common prime divisors

11 

12     while x != 1:

13         x_gcd = gcd(x, gcd_value)

14         if x_gcd == 1:

15             # x does not contain any more 

16             # common prime divisors

17             break

18         x /= x_gcd

19     if x != 1:

20         # If x and y have exactly the same common 

21         # prime divisors, x must be composed by

22         # the prime divisors in gcd_value. So

23         # after previous loop, x must be one.

24         return False

25 

26     while y != 1:

27         y_gcd = gcd(y, gcd_value)

28         if y_gcd == 1:

29             # y does not contain any more 

30             # common prime divisors

31             break

32         y /= y_gcd

33 

34     return y == 1

35 

36 def solution(A, B):

37     count = 0

38     for x,y in zip(A,B):

39         if hasSamePrimeDivisors(x,y):

40             count += 1

41     return count

 

你可能感兴趣的:(Prim)