bzoj 1041 数学推理

原题传送门http://www.lydsy.com/JudgeOnline/problem.php?id=1041

我们只需要求第一象限内(不包括坐标轴)的点数然后ans=ans*4+4就好了

首先我们知道圆上点的方程关系

x*x+y*y=r*r

那么我们变下型

Y*Y=R*R-X*X

Y*Y=(R-X)*(R+X)        ①

我们令d=gcd(r-x,r+x)

设A=(r-x)/d;

B=(r+x)/d;

因为我们要求x为整数,那么需要A,B为整数

将A,B带回①可得

A*B*d*d=y*y

因为我们要求y为整数,那么需要A*B*d*d为完全平方数

因为点在第一象限内,所以A<>B,所以A,B应为完全平方数

那么当A,B为完全平方数时,x,y为整数

那么我们可以设A=a*a; B=b*b;

则有a*a=(r-x)/d;  b*b=(r+x)/d;

那么两式相加,得到a*a+b*b=2*r/d;

那么只要a,b为整数,就可以得到一组整点

那么我们可以知道d|2*r

所以我们可以枚举2*r的因数,对于每个因数(每个因数对应一对儿因数,分别是d和2*r/d)

假设因数是d的时候,因为a<b所以2*a*a<2*r/d, 所以a*a<r/d 那么我们可以枚举a<sqrt(r/d),

对于每个a我们可以算出b,相对应的A,B应满足gcd(A,B)=1且A<>B如果满足,就累加答案

 /**************************************************************
Problem:
User: BLADEVIL
Language: Pascal
Result: Accepted
Time: ms
Memory: kb
****************************************************************/ //By BLADEVIL
var
r :int64;
ans :int64; function gcd(a,b:int64):int64;
begin
if b>a then exit(gcd(b,a)) else
if b= then gcd:=a else gcd:=gcd(b,a mod b);
end; function check(y:int64;x:extended):boolean;
var
x1 :int64;
begin
if x=trunc(x) then
begin
x1:=trunc(x);
if (gcd(x1*x1,y*y)=) and (x1*x1<>y*y) then
begin
exit(true);
end;
end;
exit(false);
end; procedure main;
var
d, a :longint;
b :extended;
begin
read(r);
for d:= to trunc(sqrt(*r)) do
begin
if (*r) mod d= then
begin
for a:= to trunc(sqrt(r/d)) do
begin
b:=sqrt(((*r)/d)-a*a);
if check(a,b) then ans:=ans+;
end;
if d<>((*r) div d) then
for a:= to trunc(sqrt(d/)) do
begin
b:=sqrt(d-a*a);
if check(a,b) then ans:=ans+;
end;
end;
end;
writeln(ans*+);
end; begin
main; end.
上一篇:BZOJ1192 [HNOI2006]鬼谷子的钱袋 数学推理


下一篇:【Cocos2d-x游戏开发】解决Cocos2d-x中文乱码的三种方法