zoukankan      html  css  js  c++  java
  • hdoj 1299 Diophantus of Alexandria

    hdoj 1299 Diophantus of Alexandria

    链接http://acm.hdu.edu.cn/showproblem.php?pid=1299

    题意:求 1/x + 1/y = 1/n (x <= y) 的组数。

    思路:转化为一个数的因子个数。

    因为x,y,z 都是整数,令 y = n+k (倒数和相等,x,y 明显大于 n),带入式子可得 x = n*n / k + n ;所以 x 的组数就与k相关了,只要 k 满足是 n*n 的约数,组数就 +1。假设 n = (p1^r1) * (p2^r2) * (p3^r3) * ... * (pn^rn),则 n 的约数个数为 (r1+1) * (r2+1) * ... * (rn+1),   n * n 可分解为 n * n = (p1^2r1) * (p2^2r2) * … *(pn^2rn), 所以 n*n 的约数个数为 cnt = (2r1+1) * (2r2+1) * … * (2rn+1)。公式中的 p1,p2,……,pn 为素数。所以就转化为求素数的问题,这里用到线性筛法求 sqrt(n)内的素数。因为 x < y, 所以把结果除以2就得到答案。

    代码

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cmath>
     4 #include<cstdio>
     5 using namespace std;
     6 
     7 typedef long int LL;
     8 const int maxv = 35000;
     9 int prime[4000], num[maxv];
    10 
    11 void prim()    //筛法求素数
    12 {
    13     int i, j, k = 1;
    14     for(i = 2; i < maxv; ++i)    num[i] = 1;
    15     prime[0] = 2, num[4] = 0;
    16     for(i = 3; i < maxv; i += 2)
    17     {
    18         if(num[i])    prime[k++] = i;
    19         for(j = 0; (j<k && i*prime[j] < maxv); ++j)
    20         {
    21             num[i*prime[j]] = 0;
    22             if(i%prime[j] == 0)    break;
    23         }
    24     }
    25 }
    26 
    27 int counter(int n)    //计算约数个数
    28 {
    29     int cnt = 1, i, j, k = 0;
    30     int q;
    31     i = (int)sqrt(n*1.0)+1;
    32     for(j = 0; prime[j] <= i; ++j)
    33     {
    34         if(n % prime[j] == 0)
    35         {
    36             q = 0;
    37             while(n%prime[j] == 0){
    38                 n = n/prime[j], q++;
    39             }
    40             cnt *= (2*q+1);
    41         }
    42     }
    43 
    44     if(n > 1)
    45         cnt *= 3;
    46     return (cnt+1)/2;
    47 }
    48 int main()
    49 {
    50     int n;
    51     int i = 1, cnt, t;
    52     prim();
    53     //freopen("hdoj1299.txt", "r", stdin);
    54     cin >> t;
    55     while(t--)
    56     {
    57         cin >> n;
    58         cnt = counter(n);
    59         cout<<"Scenario #" << i++ <<":
    " << cnt << endl << endl;
    60     }
    61     return 0;
    62 }
  • 相关阅读:
    Hadoop分布式文件系统:架构和设计
    分布式设计学习资料
    codeforces上一道贪心算法题
    优先队列实现n路归并算法O(n * lgK)
    LINUX 暂停、继续进程
    重叠(Overlapped)IO模型
    WSAEventSelect模型
    WSAEventSelect模型 应用实例,重写TCP服务器实例
    选择模型2
    第四章 数据抽象 《C++编程思想》
  • 原文地址:https://www.cnblogs.com/Duahanlang/p/3204202.html
Copyright © 2011-2022 走看看