zoukankan      html  css  js  c++  java
  • Hlg 1563 亲合数.cpp memset

    题意:

      如果a的真因子之和 = b的真因子之和,则称a和b为亲合数,现在要找出100000以内的亲合数..

      要求不出现重复的数对..

     

    思路:

      如果暴力找出100000以内所有数 (a) 的真因子和 (b) 然后看看这个和的真因子和(b)是否也等于这个数(a)..的话太暴力了..会tle..

      所以可以利用 num = p0^a0*p1^a1*p2^a2...pn^an..即任何一个数都可以看作是素数 pi的n次幂 乘以一个数..

      所以pi的0次幂到n次幂*pj的0~n次幂*..都是num的真因子..

      所以就是for循环找出所有的数的倍数加入到sum里面..

     

    Tips:

      这个真真吃了memset的亏了..

      其实以前就知道memset中初始化的值应该用二进制表示..但是一直以来直接用10进制表示都没有错~所以就没注意到了..

      结果把sum初始化为 1 的时候就出问题了..

      果然~老人的话还是要听的..

     

    Code:

    View Code
     1 #include <iostream>
     2 #include <cstring>
     3 using namespace std;
     4 
     5 int sum[100010];
     6 int main()
     7 {
     8     int i, j, k;
     9     //memset(sum, 1, sizeof(sum));
    10     for(i = 0; i < 100000; ++i)
    11         sum[i] = 1;
    12     for(i = 2; 2*i <= 100000; ++i) {
    13         j = i*2;             ///j 从 i 的两倍开始算
    14         while(j <= 100000) {
    15             sum[j] += i;          ///j 既然是从 i * n得来的..则 i 也算是 j 的真因子了..
    16             j += i;       
    17         }
    18     }
    19     for(i = 220; i <= 100000; ++i)    ///题目给出了最小的亲合数对中较小的那个就是220了..
    20     if(sum[i] > i && sum[i] <= 100000 && sum[sum[i]] == i) {
    21         cout << i << ' ' << sum[i] << endl;
    22     }
    23     return 0;
    24 }

    题目链接:http://acm.hrbust.edu.cn/index.php?m=ProblemSet&a=showProblem&problem_id=1563

  • 相关阅读:
    编程题目----约德尔测试
    编程题目----路灯
    java----java垃圾回收算法
    JAVA多线程和并发基础面试问答(转载)
    科学史上非常伟大的十位单身科学家
    MySQL----mysql57服务突然不见了的,解决方法
    linux:644、755、777权限详解
    Java 关键字 速查表
    java----鲁棒性
    习题----第六章 图(转)
  • 原文地址:https://www.cnblogs.com/Griselda/p/2769274.html
Copyright © 2011-2022 走看看