https://www.cnblogs.com/scau20110726/archive/2013/01/18/2866957.html
用反证法都可以证明上文的结论,m_isUsed这个变量一开始我用的是set,验证后发现set在数据量大的时候效率极低,我以为是因为排序导致的,改用了vector,但是结果是一样的,稍稍比set快了一点,最后还是只能用回数组
#include <iostream>
#include <cmath>
#include <cstring>
using namespace std;
class FermatVSPythagoras
{
public:
void readData(const int& iNumber);
void compute();
void outputResult();
private:
const long long gcd(long long x, long long y);
private:
int m_iNumber = 0;
int m_iCountTriple = 0;
int m_iCountNumber = 0;
bool m_isUsed[1000001];
};
void FermatVSPythagoras::readData(const int& iNumber)
{
m_iNumber = iNumber;
}
const long long FermatVSPythagoras::gcd(long long iBigger, long long iSmaller)
{
if (iSmaller == 0)
{
return iBigger;
}
return this->gcd(iSmaller, iBigger % iSmaller);
}
void FermatVSPythagoras::compute()
{
m_iCountTriple = 0;
m_iCountNumber = 0;
memset(m_isUsed, 0, sizeof(m_isUsed));
for (long long i = 1; i < sqrt(m_iNumber) + 1; i += 2)
{
for (long long j = i + 2; i * i + j * j <= 2 * m_iNumber; j += 2)
{
if (this->gcd(j, i) == 1)
{
long long x = i * j;
long long y = (j * j - i * i) / 2;
long long z = (j * j + i * i) / 2;
++m_iCountTriple;
for (int k = 1; z * k <= m_iNumber; ++k)
{
if (!m_isUsed[x * k])
{
m_isUsed[x * k] = true;
++m_iCountNumber;
}
if (!m_isUsed[y * k])
{
m_isUsed[y * k] = true;
++m_iCountNumber;
}
if (!m_isUsed[z * k])
{
m_isUsed[z * k] = true;
++m_iCountNumber;
}
}
}
}
}
}
void FermatVSPythagoras::outputResult()
{
cout << m_iCountTriple << " " << m_iNumber - m_iCountNumber << endl;
}
int main()
{
FermatVSPythagoras objFermatVSPythagoras;
int iNumber = 0;
while (cin >> iNumber)
{
objFermatVSPythagoras.readData(iNumber);
objFermatVSPythagoras.compute();
objFermatVSPythagoras.outputResult();
}
return 0;
}