方法一:朴素算法:O(n)。

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. int get_num(int n){
  4. int num=;
  5. for(int i=;i<=n;++i)
  6. if(n%i==)num++;
  7. return num;
  8. }
  9. int get_sum(int n){
  10. int tot=;
  11. for(int i=;i<=n;++i)
  12. if(n%i==)tot+=i;
  13. return tot;
  14. }
  15. int main(){
  16. int n;
  17. while(cin>>n){
  18. cout<<get_num(n)<<endl;//求n的因子个数
  19. cout<<get_sum(n)<<endl;//求n的因子数之和
  20. }
  21. return ;
  22. }

方法二:约数个数定理:O(√n)。

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. int get_num(int n){
  4. int tot=;
  5. for(int i=;i*i<=n;++i){
  6. if(n%i==){
  7. int x=;
  8. while(n%i==){
  9. n/=i;
  10. x++;
  11. }
  12. tot*=(x+);
  13. }
  14. }
  15. if(n>)tot*=;
  16. return tot;
  17. }
  18. int get_sum(int n){
  19. int tot=;
  20. for(int i=;i*i<=n;i++){
  21. if(n%i==){
  22. int mul=;
  23. while(n%i==){
  24. n/=i;
  25. mul*=i;
  26. }
  27. tot*=(mul*i-)/(i-);
  28. }
  29. }
  30. if(n>)tot*=(n+);
  31. return tot;
  32. }
  33. int main(){
  34. int n;
  35. while(cin>>n){
  36. cout<<get_num(n)<<endl;//求n的因子个数
  37. cout<<get_sum(n)<<endl;//求n的因子数之和
  38. }
  39. return ;
  40. }

实战例题:

题解报告:hdu 2521 反素数

Problem Description

反素数就是满足对于任意i(0<i<x),都有g(i)<g(x),(g(x)是x的因子个数),则x为一个反素数。现在给你一个整数区间[a,b],请你求出该区间的x使g(x)最大。

Input

第一行输入n,接下来n行测试数据
输入包括a,b, 1<=a<=b<=5000,表示闭区间[a,b].

Output

输出为一个整数,为该区间因子最多的数.如果满足条件有多个,则输出其中最小的数.

Sample Input

3
2 3
1 10
47 359

Sample Output

2 6 240

Hint

2的因子为:1 2

10的因子为:1 2 5 10
解题思路:求区间[a,b]中最小的元素x,使得所含的因子个数最大,由于数据比较小,暴力枚举区间[a,b]并套一下公式即可。时间复杂度为O($n\sqrt{n}$)。
AC代码(15ms):
  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. int n,a,b,maxnum,maxindex;
  4. int get_num(int n){//求n的因子个数
  5. int tot=;
  6. for(int i=;i*i<=n;++i){
  7. if(n%i==){
  8. int x=;
  9. while(n%i==){
  10. n/=i;
  11. x++;
  12. }
  13. tot*=(x+);
  14. }
  15. }
  16. if(n>)tot*=;
  17. return tot;
  18. }
  19. int main(){
  20. while(cin>>n){
  21. while(n--){
  22. cin>>a>>b;maxnum=;maxindex=a;
  23. for(int i=a;i<=b;++i){
  24. int tmp=get_num(i);
  25. if(tmp>maxnum){maxindex=i;maxnum=tmp;}
  26. }
  27. cout<<maxindex<<endl;
  28. }
  29. }
  30. return ;
  31. }

题解报告:hdu 1215 七夕节

Problem Description

七夕节那天,月老来到数字王国,他在城门上贴了一张告示,并且和数字王国的人们说:"你们想知道你们的另一半是谁吗?那就按照告示上的方法去找吧!"
人们纷纷来到告示前,都想知道谁才是自己的另一半.告示如下:
数字N的因子就是所有比N小又能被N整除的所有正整数,如12的因子有1,2,3,4,6.
你想知道你的另一半吗?

Input

输入数据的第一行是一个数字T(1<=T<=500000),它表明测试数据的组数.然后是T组测试数据,每组测试数据只有一个数字N(1<=N<=500000).

Output

对于每组测试数据,请输出一个代表输入数据N的另一半的编号.

Sample Input

3
2
10
20

Sample Output

1
8
22
解题思路:求n的因子数之和,简单套一下公式,时间复杂度为O($t\sqrt{n}$),最坏大概为3e8。
AC代码一(93ms):
  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. int t,n;
  4. int get_sum(int n){
  5. int tot=;
  6. for(int i=;i*i<=n;++i){
  7. if(n%i==){
  8. int mul=;
  9. while(n%i==){
  10. n/=i;
  11. mul*=i;
  12. }
  13. tot*=(mul*i-)/(i-);
  14. }
  15. }
  16. if(n>)tot*=(n+);
  17. return tot;
  18. }
  19. int main(){
  20. while(~scanf("%d",&t)){
  21. while(t--){
  22. scanf("%d",&n);
  23. printf("%d\n",get_sum(n)-n);
  24. }
  25. }
  26. return ;
  27. }

AC代码二(109ms):简单打表,时间复杂度为nlogn。

  1. #include<bits/stdc++.h>
  2. const int maxn=;
  3. using namespace std;
  4. int t,n,sum[maxn];
  5. int main(){
  6. for(int i=;i<maxn/;++i)//因子i
  7. for(int j=i*;j<maxn;j+=i)//j是i的倍数,即j的因子是i
  8. sum[j]+=i;//sum[j]表示其所有因子之和
  9. while(~scanf("%d",&t)){
  10. while(t--){
  11. scanf("%d",&n);
  12. printf("%d\n",sum[n]);
  13. }
  14. }
  15. return ;
  16. }

题解报告:hdu 1999 不可摸数

Problem Description

s(n)是正整数n的真因子之和,即小于n且整除n的因子和.例如s(12)=1+2+3+4+6=16.如果任何数m,s(m)都不等于n,则称n为不可摸数.

Input

包含多组数据,首先输入T,表示有T组数据.每组数据1行给出n(2<=n<=1000)是整数。

Output

如果n是不可摸数,输出yes,否则输出no

Sample Input

3
2
5
8

Sample Output

yes
yes
no
解题思路:题意就是给一个n(n表示为s(m)的真因子数之和),如果任意数m的真因子之和在n∈[2,1000],那么s(m)就不是不可摸数,否则为不可摸数。打表可以发现数m只需枚举到10^6便可将真因数之和为1000以内的全部找出来。于是这道题也可以直接打印出89个不可摸数,简单标记一下即可。
AC代码一(62ms):
  1. #include<bits/stdc++.h>
  2. const int maxn=;
  3. using namespace std;
  4. int t,n,sum[maxn];bool f[maxn];
  5. int main(){
  6. memset(f,false,sizeof(f));
  7. for(int i=;i<maxn/;++i)//因子i
  8. for(int j=i*;j<maxn;j+=i)//j是i的倍数,即j的因子是i
  9. sum[j]+=i;//sum[j]表示其所有因子之和
  10. for(int i=;i<maxn;++i)
  11. if(sum[i]<=)f[sum[i]]=true;//如果真因数之和在1000以内,那么sum[i]不是不可摸数
  12. while(~scanf("%d",&t)){
  13. while(t--){
  14. scanf("%d",&n);
  15. if(f[n])printf("no\n");
  16. else printf("yes\n");//n为不可摸数
  17. }
  18. }
  19. return ;
  20. }

AC代码二(0ms):

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. int t,n;bool f[];
  4. int main(){
  5. int obj[]={,,,,,,,,,,
  6. ,,,,,,,,,,,,
  7. ,,,,,,,,,,,,
  8. ,,,,,,,,,,,,
  9. ,,,,,,,,,,,,
  10. ,,,,,,,,,,,,
  11. ,,,,,,,,,,,,
  12. ,,,,,,};
  13. memset(f,false,sizeof(f));
  14. for(int i=;i<;++i)f[obj[i]]=true;//1000以内共有89个数为不可摸数
  15. while(~scanf("%d",&t)){
  16. while(t--){
  17. scanf("%d",&n);
  18. if(f[n])printf("yes\n");
  19. else printf("no\n");
  20. }
  21. }
  22. return ;
  23. }

题解报告:hdu 1299 Diophantus of Alexandria

Problem Description

Diophantus of Alexandria was an egypt mathematician living in Alexandria. He was one of the first mathematicians to study equations where variables were restricted to integral values. In honor of him, these equations are commonly called diophantine equations. One of the most famous diophantine equation is x^n + y^n = z^n. Fermat suggested that for n > 2, there are no solutions with positive integral values for x, y and z. A proof of this theorem (called Fermat's last theorem) was found only recently by Andrew Wiles.
Consider the following diophantine equation: 
1 / x + 1 / y = 1 / n where x, y, n ∈ N+ (1)Diophantus is interested in the following question: for a given n, how many distinct solutions (i. e., solutions satisfying x ≤ y) does equation (1) have? For example, for n = 4, there are exactly three distinct solutions: 
1 / 5 + 1 / 20 = 1 / 4
1 / 6 + 1 / 12 = 1 / 4
1 / 8 + 1 / 8 = 1 / 4Clearly, enumerating these solutions can become tedious for bigger values of n. Can you help Diophantus compute the number of distinct solutions for big values of n quickly?

Input

The first line contains the number of scenarios. Each scenario consists of one line containing a single number n (1 ≤ n ≤ 10^9). 

Output

The output for every scenario begins with a line containing "Scenario #i:", where i is the number of the scenario starting at 1. Next, print a single line with the number of distinct solutions of equation (1) for the given value of n. Terminate each scenario with a blank line. 

Sample Input

2
4
1260

Sample Output

Scenario #1:
3
Scenario #2:
113
解题思路:首先,根据分式等式的性质可得x、y均大于n,假设y=n+k(k≥1),将其代入1/x+1/y=1/n化简得x=n^2/k+n,因为x∈N+,所以k|n2(k≥1),即求n2的因子个数sum,则最终的答案为:(sum+1)/2,因为必定有一半的x、y这一对是重复了的,只是值互换了而已,举个例子:当n=4时,
x=     8  6   5
k=  1   2  4  8  16(n^2=16的所有因子)
y=     6  8    
显然此时有3组解,也就是满足n2/k == k,(其中k|n2)的解有(sum+1)/2组。
AC代码:
  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. typedef long long LL;int t;LL n;
  4. LL get_num(LL x){
  5. LL ans=,tp;
  6. for(LL i=;i*i<=x;++i){
  7. if(x%i==){
  8. tp=;
  9. while(x%i==)tp++,x/=i;
  10. ans*=(+*tp);
  11. }
  12. }
  13. if(x>)ans*=;
  14. return ans;
  15. }
  16. int main(){
  17. while(cin>>t){
  18. for(int i=;i<=t;++i){
  19. cin>>n;
  20. cout<<"Scenario #"<<i<<":\n"<<(get_num(n)+)/<<"\n"<<endl;
  21. }
  22. }
  23. return ;
  24. }

题解报告:NYOJ #66 分数拆分

描述

现在输入一个正整数k,找到所有的正整数x>=y,使得1/k=1/x+1/y.

输入

第一行输入一个整数n,代表有n组测试数据。
接下来n行每行输入一个正整数k

输出

按顺序输出对应每行的k找到所有满足条件1/k=1/x+1/y的组合。

样例输入

  1. 2
  2. 2
  3. 12

样例输出

  1. 1/2=1/6+1/3
  2. 1/2=1/4+1/4
  3. 1/12=1/156+1/13
  4. 1/12=1/84+1/14
  5. 1/12=1/60+1/15
  6. 1/12=1/48+1/16
  7. 1/12=1/36+1/18
  8. 1/12=1/30+1/20
  9. 1/12=1/28+1/21
  10. 1/12=1/24+1/24

解题思路:由x>=y且x、y均大于k可知1/x<=1/y,1/k-1/y<=1/y,即k<y<=2k,所以只需控制y的枚举范围即可。

AC代码:

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. int t,k;
  4. int main(){
  5. while(cin>>t){
  6. while(t--){
  7. cin>>k;
  8. for(int i=k+;i<=*k;++i)//枚举k+1~2k
  9. if(i*k%(i-k)==)printf("1/%d=1/%d+1/%d\n",k,i*k/(i-k),i);//通分,其中(i-k)|(i*k)。
  10. }
  11. }
  12. return ;
  13. }

财大情侣

Time Limit: 2000/1000ms (Java/Others)

Problem Description:

  1. 高考完终于来到梦寐以求的财经大学,男三女七有木有!食堂吃饭前后左右三排都是女生有木有!该学校总共有n个人,每个人都有对应自己的魅力值,从1n。现规定每个人的情商为每个人魅力值的约数(不包括本身)之和。在广财有个很神奇的事情,当一个人的情商刚好等于另一个的魅力值的时候,这两个人就meant to be情侣(不是一男一女怎么办?随便吧)。
  2. 如:2201+2+4+5+10+11+20+22+44+55+110=284
  3.  2841+2+4+71+142=220
  4. 这样魅力值为220284的就成为一对啦。
  5. 给定两个数,ab,找出所有ab之间(inclusive)成对的。

Input:

  1. 输入包含多组测试数据,每组数据输入两个数a,b (0<=a,b<=100000).

Output:

  1. 对于每组测试,输出ab之间的所有情侣。每对情侣占一行,魅力值小的在前面。对于多对情侣,按情侣中魅力值小的排序。参考sample output

Sample Input:

  1. 200 1300
  2. 1 200

Sample Output:

  1. 220 284
  2. 1184 1210
  3. NO
    解题思路:求每个数的所有真因子之和,简单打个表再判断一下即可。
    AC代码:
  1. #include<bits/stdc++.h>
  2. const int maxn=;//范围大一点,否则会出现越界的情况
  3. using namespace std;
  4. int a,b,x,sum[maxn];bool flag;
  5. int main(){
  6. for(int i=;i<maxn/;++i)//求因子数之和
  7. for(int j=i*;j<maxn;j+=i)//j初始为i的2倍,以后以i的步长增长,累加j的真因子
  8. sum[j]+=i;
  9. while(cin>>a>>b){
  10. if(a>b)swap(a,b);flag=false;
  11. for(int i=a;i<=b;++i)//先判断是不是一对情侣,并且前面的因子数之和x要在区间范围内,且前一个数i要小于后一个数x
  12. if(i==sum[x=sum[i]]&&x<=b&&i<x){flag=true;cout<<i<<' '<<x<<endl;}
  13. if(!flag)cout<<"NO"<<endl;
  14. }
  15. return ;
  16. }

求n的因子个数与其因子数之和的更多相关文章

  1. Soldier and Number Game---cf546D(打表求n的素因子个数)

    题目链接:http://codeforces.com/problemset/problem/546/D 题意: 给出一个n,n开始是a!/b!,每次用一个x去整除n得到新的n,最后当n变成1的时候经过 ...

  2. Almost All Divisors(求因子个数及思维)

    ---恢复内容开始--- We guessed some integer number xx. You are given a list of almost all its divisors. Alm ...

  3. LightOj1028 - Trailing Zeroes (I)---求因子个数

    题目链接:http://lightoj.com/volume_showproblem.php?problem=1028 题意:给你一个数 n (1<=n<=10^12), 然后我们可以把它 ...

  4. POJ 2992 Divisors (求因子个数)

    题意:给n和k,求组合C(n,k)的因子个数. 这道题,若一开始先预处理出C[i][j]的大小,再按普通方法枚举2~sqrt(C[i][j])来求解对应的因子个数,会TLE.所以得用别的方法. 在说方 ...

  5. Acdream1084 寒假安排 求n!中v因子个数

    题目链接:pid=1084">点击打开链接 寒假安排 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 128000/64000 ...

  6. Trailing Zeroes (I) LightOJ - 1028(求因子个数)

    题意: 给出一个N 求N有多少个别的进制的数有后导零 解析: 对于一个别的进制的数要转化为10进制 (我们暂且只分析二进制就好啦) An * 2^(n-1) + An-1 * 2^(n-2) + `` ...

  7. 第13届景驰-埃森哲杯广东工业大学ACM程序设计大赛-等式(求$N^2$的因子个数)

    一.题目链接 https://www.nowcoder.com/acm/contest/90/F 二.题面 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32768K,其他语言655 ...

  8. 求n!中因子k的个数

    思路: 求n的阶乘某个因子k的个数,如果n比较小,可以直接算出来,但是如果n很大,此时n!超出了数据的表示范围,这种直接求的方法肯定行不通.其实n!可以表示成统一的方式. n!=(km)*(m!)*a ...

  9. BZOJ3994:约数个数和(莫比乌斯反演:求[1,N]*[1,M]的矩阵的因子个数)

    Description  设d(x)为x的约数个数,给定N.M,求   Input 输入文件包含多组测试数据. 第一行,一个整数T,表示测试数据的组数. 接下来的T行,每行两个整数N.M. Outpu ...

随机推荐

  1. mysql读写分离(主从复制)实现

    mysql主从复制 怎么安装mysql数据库,这里不说了,仅仅说它的主从复制.过程例如以下: 主从最好都是同一种系统比方都是linux,或者都是windows,当然混合着也是能够成功,不解释了 1.主 ...

  2. Python 002- 爬虫爬取淘宝上耳机的信息

    参照:https://mp.weixin.qq.com/s/gwzym3Za-qQAiEnVP2eYjQ 一般看源码就可以解决问题啦 #-*- coding:utf-8 -*- import re i ...

  3. Jetty的JNDI数据源

    一. 此处绑定的数据源是以 DBCP 为实现.首先必须将数据库驱动(这里用了MYSQL数据库)和DBCP所需要的 Jar 包复制到 Jetty 根目录的 lib 目录下.DBCP主要需要以下3个文件: ...

  4. mybatis xml文件解析

    1 parameterType 如果参数只有一个,比如一个id,即int类型的id,那么parameterType直接是int. 如果参数有多个,那么就用表中一行对应的类,默认是类的名字和表中列的名字 ...

  5. 20170218 OO-ALV标准工具栏按钮

    原文地址:OO ALV 工具栏对于的功能码   图标与对应的 功能码 明细 &DETAIL 检查 &CHECK 刷新 &REFRESH 剪切 &LOCAL&CU ...

  6. 将异常(getStackTrace)转化成String

    方法一: private static String getStackMsg(Exception e) { StringBuffer sb = new StringBuffer(); StackTra ...

  7. 微信小程序template使用

    当您的项目需要多次使用同一个布局和样式的时候,您就可以考虑使用template(模板)来减少冗余代码. 使用方式: 1.新建一个template文件夹来存放您的通用模板: 2.在文件夹里面新建一个wx ...

  8. ajax访问json文件缓存问题

    ajax访问json文件,json文件改动,访问的时候也不能及时看到改动后的内容. 这是因为浏览器缓存的原因. 在这时候就需要清除浏览器的缓存或者加上一个标记,让ajax访问文件的时候知道这是一个新的 ...

  9. mysql数据库引擎InnoDB和MyISAM的区别

    InnoDB支持行级锁和表级锁(默认行级锁),支持事务,外部键等:大量的insert和update更快等.只有通过索引条件检索数据,InnoDB 才使用行级锁,否则,InnoDB 将使用表锁. MyI ...

  10. Linux时间子系统之(一):时间的基本概念【转】

    本文转载自:http://www.wowotech.net/timer_subsystem/time_concept.html 本文使用Q & A的方式来和大家以前探讨一下时间的基本概念 一. ...