Vijos P1786 质因数分解【质因数分解】
背景
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;
}
 
                    
                     
                    
                 
                    
                 
                
            
         
 
         浙公网安备 33010602011771号
浙公网安备 33010602011771号