Eddy’s research I(HDU 1164)
Problem Description
Eddy’s interest is very extensive, recently he is interested in prime number. Eddy discover the all number owned can be divided into the multiply of prime number, but he can’t write program, so Eddy has to ask intelligent you to help him, he asks you to write a program which can do the number to divided into the multiply of prime number factor .
Input
The input will contain a number 1 < x<= 65535 per line representing the number of elements of the set.
Output
You have to print a line in the output for each entry with the answer to the previous question.
Sample Input
11
9412
Sample Output
11
2213*181
解题思路:分解质因数模板题。如果当前的数已经是素数,可以直接输出。如果不是素数,则分解质因数。
AC代码:
#include <iostream>
#include <cstring>
#include <string>
using namespace std;
int main()
{
int n;
while (cin >> n)
{
string res;//用来存出结果
int pos = 0;//判断当前的因子是否是第一个因子
for (int i = 2;i <= n;i++)
{
while (n % i == 0)//找到因子
{
if (pos != 0) res += "*";
res += to_string(i);//将其转化为字符串存储在结果中
pos ++;
n /= i;//取出因子之后要更新输入的数
}
}
cout << res << endl;
}
return 0;
}
反素数(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
解题思路:求解约数的个数模板题
AC代码:
#include <iostream>
using namespace std;
/*
//暴力法:返回n的约数个数(time:343MS)
int cal_diviNum(int n)
{
int sum = 0;
for (int i = 1;i <= n;i++)//枚举因子
if (n % i == 0)
sum ++;
return sum;
}
*/
//x = p0^k0 + p1^k1 + p2^k2 + ... + pm^km
//约数的个数 = (k0+1) * (k1+1) + (k2+1) + ... + (km+1)
//(time:15MS)
int cal_diviNum(int n)
{
int sum = 1;
//枚举质因子,枚举到sqrt(n)即可
for (int i = 2;i <= n / i;i++)
{
int k = 0;//k0 k1 k2 k3 ... km
while (n % i == 0)//找到了质因子
{
k ++;
n /= i;
}
sum *= (k + 1);
}
if (n > 1) sum *= (1 + 1);
return sum;
}
int main()
{
int T; cin >> T;
while (T--)
{
int a,b; cin >> a >> b;
int diviNum,ans = -1;
int num = -1;//保存具有最大约数个数的那个数
for (int i = a;i <= b;i++)
{
diviNum = cal_diviNum(i);//计算i约数的个数
if (ans < diviNum)//如果数字i的约数的个数大于ans
{
ans = diviNum;//更新ans
num = i;
}
}
cout << num << endl;
}
// cout << cal_diviNum(6) << endl;
return 0;
}
七夕节(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
解题思路:求解约数之和模板题。本题需要注意的是12的约数本来有1、2、3、4、6、12,但是在本题中约数不包括它本身。另外本题数据量大,因此需要使用scanf
以及printf
AC代码:
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
const int N = 500005;
int vis[N],prime[N],pcnt;
void init()//埃氏筛模板
{
vis[0] = vis[1] = 1;//0、1不是质数
for (int i = 2;i < N;i++)
{
if (!vis[i])//vis[i]==0表示i是质数
{
prime[pcnt++] = i;
for (int j = i + i;j < N;j += i)
vis[j] = 1;//j不是质数
}
}
}
int cal_diviSum(int n)//计算n的约数之和
{
int result = 1;
for (int i = 0;i < pcnt && prime[i] <= n / prime[i];i++)//一个有"=",一个没"="
{
int cnt = 0;//约数pi的个数
while (n % prime[i] == 0)//找到约数
{
cnt++;//统计质因子的个数
n /= prime[i];//更新n的值
}
//质因子prime[i]有cnt个
int sum = 0,base = 1;
for (int j = 0;j <= cnt;j++)
{
sum += base;
base *= prime[i];
}
result *= sum;
}
//如果最后n > 1,说明还剩一个质数
if (n > 1) result *= (1 + n);
return result;
}
int main()
{
init();//先筛质数
int T; scanf("%d",&T);
while (T --)
{
int n; scanf("%d",&n);
printf("%d\n",cal_diviSum(n) - n);//本题中约数不包括自己
}
/*
for (int i = 0;i <= 10;i++) cout << prime[i] << " ";
2 3 5 7 11 13 17 19 23 29 31
*/
return 0;
}