zoukankan      html  css  js  c++  java
  • 【BZOJ】【1041】【HAOI2008】圆周上的点

    数学


      orz hzwer

      完全不会做……

      很纠结啊,如果将来再遇到这种题,还是很难下手啊……

    引用题解:

    【分析】:

    样例图示:

    首先,最暴力的算法显而易见:枚举x轴上的每个点,带入圆的方程,检查是否算出的值是否为整点,这样的枚举量为2*N,显然过不了全点。

    然后想数学方法。

    有了上面的推理,那么实现的方法为:

    枚举d∈[1,sqrt(2R)],然后根据上述推理可知:必先判d是否为2R的一约数。

    此时d为2R的约数有两种情况:d=d或d=2R/d。

    第一种情况:d=2R/d。枚举a∈[1,sqrt(2R/2d)] <由2*a*a < 2*R/d转变来>,算出对应的b=sqrt(2R/d-a^2),检查是否此时的A,B满足:A≠B且A,B互质 <根据上面的推理可知必需满足此条件>,若是就将答案加1

    第二种情况:d=d。枚举a∈[1,sqrt(d/2)] <由2*a*a < d转变来>,算出对应的b=sqrt(d-a^2),检查是否此时的A,B满足:A≠B且A,B互质 <根据上面的推理可知必需满足此条件>,若是就将答案加1

    因为这样只算出了第一象限的情况<上面枚举时均是从1开始枚举>,根据圆的对称性,其他象限的整点数与第一象限中的整点数相同,最后,在象限轴上的4个整点未算,加上即可,那么最后答案为ans=4*第一象限整点数+4

    【时间复杂度分析】:

    枚举d:O(sqrt(2R)),然后两次枚举a:O(sqrt(d/2))+O(sqrt(R/d)),求最大公约数:O(logN)

     1 /**************************************************************
     2     Problem: 1041
     3     User: Tunix
     4     Language: C++
     5     Result: Accepted
     6     Time:192 ms
     7     Memory:816 kb
     8 ****************************************************************/
     9  
    10 //BZOJ 1000
    11 #include<cmath>
    12 #include<cstdio>
    13 using namespace std;
    14 typedef long long LL;
    15 typedef double lf;
    16 /******************tamplate*********************/
    17 LL r,ans;
    18 LL gcd(LL x,LL y){return y?gcd(y,x%y):x;}
    19 bool check(LL y,lf x){
    20     if (x==floor(x)){
    21         LL x1=x;
    22         if (gcd(x1*x1,y*y)==1 && x1*x1!=y*y)
    23             return 1;
    24     }
    25     return false;
    26 }
    27 int main(){
    28     scanf("%lld",&r);
    29     for(LL d=1;d<=sqrt(2*r);d++)
    30         if (2*r%d==0){
    31             for(LL a=1;a<=(LL)sqrt(2*r/(2*d));a++){
    32                 lf b=sqrt((2*r)/d-a*a);
    33                 if (check(a,b))ans++;
    34             }
    35             if (d!=2*r/d){
    36                 for(LL a=1;a<=(LL)sqrt(d/2);a++){
    37                     lf b=sqrt(d-a*a);
    38                     if (check(a,b))ans++;
    39                 }
    40             }
    41         }
    42     printf("%lld
    ",ans*4+4);
    43     return 0;
    44 }
    View Code

    1041: [HAOI2008]圆上的整点

    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 2376  Solved: 1019
    [Submit][Status][Discuss]

    Description

    求一个给定的圆(x^2+y^2=r^2),在圆周上有多少个点的坐标是整数。

    Input

    r

    Output

    整点个数

    Sample Input

    4

    Sample Output

    4

    HINT

    n<=2000 000 000

    Source

    [Submit][Status][Discuss]
  • 相关阅读:
    软件工程概论第一阶段站立会议(八)
    软件工程概论第一阶段站立会议(七)
    浪潮之巅阅读笔记(一)
    软件工程概论学习进度条(四)
    软件工程概论第一阶段站立会议(六)
    软件工程概论第一阶段站立会议(五)
    软件工程概论第一阶段站立会议(四)
    易校小程序典型需求分析
    pip/easy_install failure: failed to create process
    mysq修改密码
  • 原文地址:https://www.cnblogs.com/Tunix/p/4428004.html
Copyright © 2011-2022 走看看