背景
NOIP2012普及组第一题
描述
已知正整数n是两个不同的质数的乘积试求出较大的那个质数。
格式
输入格式
输入只有一行包含一个正整数n。
输出格式
输出只有一行包含一个正整数p, 即较大的那个质数。
样例1
样例输入1
21
样例输出1
7
限制
1S
提示
【数据范围】 对于60%的数据,6 ≤ n ≤ 1000。 对于100%的数据,6 ≤ n ≤ 2*10的9次方
来源
NOIP2012普及组第一题
问题链接: Vijos P1786 质因数分解
问题分析:
如果一个数n是两个素数的乘积,那么其中一个素数必然小于或等于n的开平方。
程序说明:
这里给出两种程序。
先做的第二种,追求时间上快,ACM程序一般都需要这么做。转念一想,试一下最简单的做法,没想到也通过了。
题记:
一般而言,想把程序做的快一些,不仅需要付出空间的代价,而且手续繁杂。
参考链接:(略)
AC的C++程序如下:
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
long n;
cin >> n;
if(n % 2 == 0)
cout << n / 2 << endl;
else {
int start = sqrt(n) / 2;
start = start * 2 + 1;
for(int i=start; i>=3; i-=2) {
if(n % i == 0) {
cout << n / i << endl;
}
}
}
return 0;
}
AC的C++程序如下:
#include <iostream>
using namespace std;
const int N = 44721; // 2*10的9次方的开方
long prime[N+2] = {0, 0, 1};
// 计算整数开方函数
long sqrt(long n)
{
long a, b, m;
a = 1;
b = n;
for(;;) {
m = (a + b) / 2;
if (m == a || m == b)
return m;
if (m * m > n)
b = m;
else
a = m;
}
}
// 筛选法求最小的n个素数
int esieve(long prime[], int n)
{
for(int i=3; i<=n; i++) {
prime[i++] = 1;
prime[i] = 0;
}
for(int i=3; i*i<=n; i+=2) {
if(prime[i]) {
for(int j=i+i; j<=n; j+=i) //进行筛选
prime[j] = 0;
}
}
// 整理素数放在数组的前面,小于或等于n的素数共k个
int k = 0;
for(int i=2; i<=n; i++)
if(prime[i])
prime[k++] = i;
return k;
}
int main()
{
long n;
cin >> n;
int m = esieve(prime, sqrt(n));
for(int i=m-1; i>=0; i--)
if(n % prime[i] == 0) {
cout << n / prime[i] << endl;
break;
}
return 0;
}