uva10392 Factoring Large Numbers

uva10392 Factoring Large Numbers

本文涉及的知识点是,使用线性筛选法得到素数表

Table of Contents

1 题目

====================

Problem F: Factoring Large Numbers

One of the central ideas behind much cryptography is that factoring large numbers is computationally intensive. In this context one might use a 100 digit number that was a product of two 50 digit prime numbers. Even with the fastest projected computers this factorization will take hundreds of years.

You don't have those computers available, but if you are clever you can still factor fairly large numbers.

 

Input

The input will be a sequence of integer values, one per line, terminated by a negative number. The numbers will fit in gcc's long long int datatype. You may assume that there will be at most one factor more than 1000000.

Output

Each positive number from the input must be factored and all factors (other than 1) printed out. The factors must be printed in ascending order with 4 leading spaces preceding a left justified number, and followed by a single blank line.

Sample Input

90
1234567891
18991325453139
12745267386521023
-1

Sample Output

    2
    3
    3
    5

    1234567891

    3
    3
    13
    179
    271
    1381
    2423

    30971
    411522630413

====================
 

2 思路

这是一个分解质因数问题,因为题目说明了数字不超过long long int表示的数,所以 这不是一个大数问题。基本的思路是首先得到素数表,再用输入的大数对素数表中的 素数依次作除法运算。

关键的地方有两个,一个是素数表的获得。这里使用了线性筛选法,把所有的合数筛去, 关键的思想在于每个合数都是被它的最小素因子筛去的,且只会被筛一次。

关键代码在于:

 

 if (!i%prime[k]) break;

之所以可以break在于,i可以整除prime[k], 在于下一次循环要筛的数字i*prime[k+1]一定已经被prime[k]筛过了,因为素数表是按大小排列的,prime[k]比prime[k+1]小,而每个合数都是被它最小的素因子筛出去的。

 


第二个点在于题目中已经说明,最多有一个素因子大于1000000,所以素数表只开到1000000就可以了, 如果遍历完素数表输入的数字还没有变成1,那么,将其最终结果输出就可以了,这个结果 就是那个大于1000000的因子,否则它一定可以被1000000内的素数整除。


 

3 代码

#include <stdio.h>
#include <string.h>

#define N 1000000
long long prime[N];
short is_prime[N];

long long get_prime (long long prime[], long long n) {
  long long i, j, k;
  memset (is_prime, 0, sizeof(is_prime[0])*n);  

  j = 0;
  for (i=2; i<n; i++) {
    if (!is_prime[i]) prime[j++] = i;
    for (k=0; k<j && i*prime[k]<n; k++) {
      is_prime[ i*prime[k] ] = 1;
      if (!i%prime[k]) break;
    }
  }

  return j;
}

int main() {
  long long n;
  long long i;
  long long prime_num;

  prime_num = get_prime (prime, N);

  while (scanf ("%lld", &n) != EOF) {
    if (n == -1) break;

    for (i=0; i<prime_num && n!=1; i++) {
      while (n % prime[i] == 0) {
        printf ("    %lld\n", prime[i]);
        n /= prime[i];
      }
    }
    if (n != 1) printf ("    %lld\n", n);
    printf ("\n");
  }

  return 0;
}


 

 

posted @ 2013-08-06 18:39  jlins  阅读(428)  评论(0编辑  收藏  举报