[Codility] CommonPrimeDivisors
A 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