我为拼图型网站编写了一个解决方案。在使用最新g ++的XCode上,我的代码编译得很好。在他们的网站(和键盘)上,我的输出是负数。有人可以帮助我理解为什么,因为我老实说难倒。
#include <iostream>
#include <cmath>
#include <vector>
#include <map>
using namespace std;
vector<int> getAllPrimes(vector<int> primesArray, int n)
{
vector<int> numArray (n+1, 1);
for (int i = 2; i <= n; i++)
{
if (numArray[i] == 1)
{
primesArray.push_back(i);
for (int k = i; k <= n; k+= i)
{
numArray[k] = 0;
}
}
}
return primesArray;
}
int main()
{
long n = 32327;
if (n == 1)
{
printf("%ld\n", n);
return EXIT_SUCCESS;
}
map <int, int> primeMap;
map <int, int>::iterator itr;
vector<int> primesArray;
primesArray = getAllPrimes(primesArray, n);
while(!primesArray.empty())
{
long currPrime = primesArray.back(), curr = currPrime;
while (currPrime <= n)
{
primeMap[curr] += (int)floor(n/currPrime);
currPrime *= curr; //multiply currPrime to add another factor of curr.
}
primesArray.pop_back();
}
//get the number of divisors of n!
long numDivisors = 1;
for (itr=primeMap.begin(); itr != primeMap.end(); itr++)
{
numDivisors *= ((*itr).second*2)+1; //power of each prime + 1, * 2 because you need the number of divisors of the square of n!
numDivisors = numDivisors % 1000007;
}
printf("%ld\n", numDivisors);
return 0;
}
通常“long n”应该从标准输入读取1到1百万之间的整数,但我只是分配了一个值来模拟它。
我已将代码放在键盘中:http://codepad.org/RpPFuLzX。如您所见,输出为-596936
,而在我的机器上则为656502
(这是正确的输出)。到底是怎么回事?
答案 0 :(得分:5)
很可能的罪魁祸首是CodePad和其他站点正在32位系统上进行编译,其中long
长度为4个字节(http://codepad.org/W00vCFIN)。在OS X上,一切都默认为64位,在这些系统上(但不是Windows),长度为8个字节。因此,您在某些时候会溢出计算。
如果您依赖于特定的整数大小,请使用stdint.h
这是一个改编版本,使用int64_t
符合您的预期输出:http://codepad.org/Owsl3ClR
答案 1 :(得分:1)
您得到不同结果的原因是, long 等数据类型在32位和64位上的处理方式不同。 Mac OS X使用LP64数据模型,其中64位模式下长64位,32位模式下长32位。如果你分别为32位和64位构建程序,你会看到不同的结果。
一种流行的解决方案是使用指定位数的数据类型,如uint64_t
,对于大小为64位的无符号整数而不是long
,根据标准,等于或者大于int 。
答案 2 :(得分:0)
粘贴到Comeau online,我得到:
"ComeauTest.c", line 49: error: more than one instance of overloaded function
"floor" matches the argument list, the choices that match are:
function "floor(long double)"
function "floor(float)"
function "floor(double) C"
function "std::floor(long double)"
function "std::floor(float)"
The argument types that you used are: (long)
primeMap[curr] += (int)floor(n/currPrime);