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





posted on 2017-05-11 10:02  海岛Blog  阅读(227)  评论(0编辑  收藏  举报

导航