Problem Specification | Value |
---|---|
Time Limit | 10 Sec |
Memory Limit | 162 MB |
Submit | 3175 |
Solved | 1405 |
Description
求一个给定的圆 (x2+y2=r^2), 在圆周上有多少个点的坐标是整数.
Input
只有一个正整数 n, n<=2000 000 000
Output
整点个数
Sample Input
4
Sample Output
4
HINT
Source
带优化的一个 sqrt () 检查...... 其实直接想一想就可以出来时间复杂度了, 大概在 O (sqrt (n)) 左右, 但是最开始我是想错了的, 以为需要 O (n^2) 才能解出来.
不多说, 直接上代码.
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cmath>
using namespace std;
typedef long long ll;
typedef double lf;
ll z;
ll res = 0;
ll gcd(ll x, ll y)
{
if (y == 0) return x;
return gcd(y, x % y);
}
ll sqrt_invocation(ll x)
{
ll y = sqrt(x);
return y * y == x ? y : -1;
}
void check(ll a, ll b)
{
if (b <= 0) return ;
if (gcd(a, b) == 1 && a != b)
res++;
return ;
}
int main(int argc, char** argv)
{
scanf("%lld", &z);
// Let x^2 + y^2 = z^2.
lf sqrt_2z = sqrt(lf(2 * z));
for (ll p = 1; p <= sqrt_2z; p++)
if ((2 * z) % p == 0) {
ll sqrt_2z_2p = sqrt(lf(z) / p); // = 2z / 2p
for (ll a = 1; a <= sqrt_2z_2p; a++) {
ll b = sqrt_invocation(2 * z / p - a * a);
check(a, b);
}
if (p * p != 2 * z) {
ll sqrt_p_2 = sqrt(lf(p) / 2);
for (ll a = 1; a <= sqrt_p_2; a++) {
ll b = sqrt_invocation(p - a * a);
check(a, b);
}
}
}
printf("%lld\n", res * 4 + 4);
return 0;
}
from pydatagen import *
r = randrange(100, 2 * 10**9)
printf('%d\n' % r)