这个问题是在接受采访时给我的,我无法真正找到解决方案:
如果我得到一个包含一些数字的数组,并且我可以无数次地将每个数字加倍或加倍,我只需要找出这些数字是否可以相互相等,如何我可以做吗?什么是可能的算法呢?
答案 0 :(得分:2)
让我们从该数组中获取两个元素,并将其称为a
和b
。现在让它们加倍并加倍,直到它们相等:
a * 2^i * 3^j == b * 2^m * 3^n
由此我们可以得出结论,如果(通过以上等式的简单变换),这是有效的
a / (2^m * 3^n) == b / (2^i * 3^j)
起初,这似乎没有用。但请记住,每个数字都可以表示为其主要因素的乘积:
c = 2^u * 3^v * 5^w * 7^x * 11^y * ...
(u, v, w, ... may be 0)
现在将其应用于上一个等式,如果我们将m
和n
等于2和3(u
和v
的数量,那么剩下的就是a
将是其所有主要因素2和3的乘积。对b
执行相同操作,然后比较结果。
现在将其纳入算法(并将其应用于更多数字)并非如此困难(尽管我们需要注意,因为我们肯定不想计算所有元素的所有素因子)。
2
,直至2
3
2
2
即可
3
false
true
答案 1 :(得分:1)
如果数字不是很大,你可以计算每个的(素数)因子分解 删除所有2和3,并比较排序的休息。
示例1:
Numbers: 2 12 6
Factorization: (2) (2*2*3) (2*3)
2 and 3 removed: () () ()
Everything equal: Yes, so this numbers can be made equal
示例2:
Numbers: 4 14
Factorization: (2*2) (2*7)
2 and 3 removed: () (7)
Everything equal: No, so this numbers can´t be made equal
基本上,对于每个数字,如果将其除以2和/或3,则计算剩余部分 尽可能经常地。如果余数相等......
答案 2 :(得分:1)
您的意思是least common multiple吗?
答案 3 :(得分:1)
取出数组中的每个数字,并从O(n log n)中删除所有因子2和3。然后检查数组中的所有数字是否相等。
示例代码:
#include <iostream>
using namespace std;
int remove2And3(int x) {
while(x%2==0) x/=2;
while(x%3==0) x/=3;
return x;
}
int main() {
int n;
while(cin >> n) {
int first; cin >> first;
first = remove2And3(first);
bool answer = true;
for(int i=1; i<n; i++) {
int other; cin >> other;
other = remove2And3(other);
answer &= first == other;
}
cout << (answer ? "YES" : "NO") << endl;
}
}
答案 4 :(得分:0)
尝试将每个数字分开,直到它被2或3整除并将其置于设定状态 最后检查设置大小是否等于1,如果设置大小为1则是否则否。
以下是c ++解决方案:
#include <iostream>
#include <set>
int main()
{
int tc, num;
std::set<int> ss;
while (std::cin >> tc) {
for (int i = 0; i < tc; i++) {
std::cin >> num;
while (num%2 == 0 || num % 3 == 0) {
if (num % 2 == 0)
num /= 2;
else if (num % 3 == 0)
num /= 3;
}
ss.insert(num);
}
if (ss.size() == 1)
std::cout << "Yes" << std::endl;
else std::cout << "No" << std::endl;
ss.clear();
}
return 0;
}
答案 5 :(得分:0)
行each item can be doubled or tripled
表示您可以按2
和3
将每个数字乘以任意次数。这种情况的后果是,除了2
和3
的权力之外,数字的素数因子化不会发生变化。这样做的推论是,如果两个数字具有相同的素数因子分解,只有2
和3
的幂不同,它们可以相等。为了澄清,我对两个数字相等的解释是,这两个数字乘以不同数量的2s
和3s
可以相互相等。
在两个数字上检查这个的简单函数如下:
bool check(int a, int b)
{
while (a%2 == 0)
a = a/2;
while (a%3 == 0)
a = a/3;
while (b%2 == 0)
b = b/2;
while (b%3 == 0)
b = b/3;
return (a == b);
}
您可以轻松地将其扩展为检查整个数组。
答案 6 :(得分:-1)
这不是常见的分频器问题吗?只要看看你是否能找到更大的数字,可以用任何给定数字产生除数的整数。
所以有{2,3,5}数组,你可以说是,就像30这样。
答案 7 :(得分:-3)
将元素从第二个索引除以最后一个并乘以第一个元素。
Ex: array [2, 3, 4, 7, ...]
So now [2, 3/3 *2, 4/4 * 2, 7 / 7 * 2...]
如果元素为零,则不要只添加第一个元素。