在一个名为UnfriendlyNumbers的访谈街上有一个问题。问题是这样的 -
有一个友好号码和N个不友好号码。我们想知道有多少数字确切地划分了友方号码,但没有划分任何不友好的号码。 样本输入: 8 16 2 5 7 4 3 8 3 18 样本输出: 1
我能想象的所有测试用例都能正确执行,但出于某种原因,网站认为它对于一组测试用例是不正确的。你们看到代码/逻辑中有任何错误吗?
void get_factors(unsigned long n, vector<unsigned long> &factors)
{
unsigned long sqrt = pow(n, 0.5);
for (unsigned long i = 1; i < sqrt; i++) {
if (n%i == 0) {
factors.push_back(i);
factors.push_back(n/i);
}
}
if (n%sqrt == 0) {
factors.push_back(sqrt);
}
}
int
main(int argc, char *argv[])
{
unsigned int n;
unsigned long k, j;
cin >> n >> k;
if (n == 0 || k == 0) {
cout << 0 << endl;
return 0;
}
set<unsigned long> unfriendly;
for (int i = 0; i < n; i++) {
cin >> j;
unfriendly.insert(j);
}
vector<unsigned long> factors;
get_factors(k, factors);
unsigned int count = factors.size();
for (int i = 0; i < factors.size(); i++) {
for (set<unsigned long>::iterator it = unfriendly.lower_bound(factors[i]);
it != unfriendly.end();
it++)
{
if (*it % factors[i] == 0) {
count--;
break;
}
}
}
cout << count;
}
答案 0 :(得分:4)
您的get_factors
不正确。对于30或35之类的数字,省略了一些除数。
sqrt
是不超过平方根的最大整数,但在n == sqrt*(sqrt+1)
或n == sqrt*(sqrt+2)
时,您不会记录sqrt+1
resp。 sqrt+2
作为除数。
此外,还有可能
unsigned long sqrt = pow(n, 0.5);
如果n
足够大,会产生错误的结果,更好地调整
while(sqrt > n/sqrt) --sqrt;
while(sqrt+1 <= n/(sqrt+1)) ++sqrt;
而且,unsigned long
可能不够大,以确保安全使用unsigned long long
。
除此之外,我看到的唯一可能失败的是,如果任何数字为0。
for (set<unsigned long>::iterator it = unfriendly.lower_bound(factors[i]);
it != unfriendly.end();
it++)
如果不友好的数字为0,将失败;如果友方号码为0,则所有投注均已关闭(如果任何不友好的数字为0,则答案为0,否则为无穷大。)
答案 1 :(得分:0)
使用GCD获取不友好号码和友好号码K之间的公约除数。 O(N)
然后在O(sqrt(K))中得到K的除数。
循环cmn_div和k的div,以O(N * sqrt(K))得到答案