背景
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; }