[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

 

posted @ 2015-04-28 19:37  Eason Liu  阅读(939)  评论(0编辑  收藏  举报