zoukankan      html  css  js  c++  java
  • 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如果满足,就累加答案

     1 /**************************************************************
     2     Problem: 1041
     3     User: BLADEVIL
     4     Language: Pascal
     5     Result: Accepted
     6     Time:136 ms
     7     Memory:224 kb
     8 ****************************************************************/
     9  
    10 //By BLADEVIL
    11 var
    12     r                           :int64;
    13     ans                         :int64;
    14      
    15 function gcd(a,b:int64):int64;
    16 begin
    17     if b>a then exit(gcd(b,a)) else
    18     if b=0 then gcd:=a else gcd:=gcd(b,a mod b);
    19 end;
    20      
    21 function check(y:int64;x:extended):boolean;
    22 var
    23     x1                          :int64;
    24 begin
    25     if x=trunc(x) then
    26     begin
    27         x1:=trunc(x);
    28         if (gcd(x1*x1,y*y)=1) and (x1*x1<>y*y) then
    29         begin
    30             exit(true);
    31         end;
    32     end;
    33     exit(false);
    34 end;
    35      
    36 procedure main;
    37 var
    38     d, a                        :longint;
    39     b                           :extended;
    40 begin
    41     read(r);
    42     for d:=1 to trunc(sqrt(2*r)) do
    43     begin
    44         if (2*r) mod d=0 then
    45         begin
    46             for a:=1 to trunc(sqrt(r/d)) do
    47             begin
    48                 b:=sqrt(((2*r)/d)-a*a);
    49                 if check(a,b) then ans:=ans+1;
    50             end;
    51             if d<>((2*r) div d) then
    52             for a:=1 to trunc(sqrt(d/2)) do
    53             begin
    54                 b:=sqrt(d-a*a);
    55                 if check(a,b) then ans:=ans+1;
    56             end;
    57         end;
    58     end;   
    59     writeln(ans*4+4);
    60 end;
    61  
    62 begin
    63     main;
    64  
    65 end.
  • 相关阅读:
    中海洋朗讯杯比赛总结[2014年12月]
    青理工ACM比赛总结和反思[2014年11月]
    程序员技术练级攻略
    一天能学会的计算机技术
    UVa 1597
    回滚机制
    超时和重试机制
    降级特技
    限流详解
    隔离术
  • 原文地址:https://www.cnblogs.com/BLADEVIL/p/3433558.html
Copyright © 2011-2022 走看看