zoukankan      html  css  js  c++  java
  • UVA 10539 Almost Prime Numbers( 素数因子)

    Problem A
    Almost Prime Numbers
    Time Limit: 1 second

    Almost prime numbers are the non-prime numbers which are divisible by only a single prime number. In this problem your job is to write a program which finds out the number of almost prime numbers within a certain range.

    Input
    First line of the input file contains an integer N (N <= 600) which indicates how many sets of inputs are there. Each of the next N lines make a single set of input. Each set contains two integer numbers low and high (0 < low <= high < 1012).

    Output
    For each line of input except the first line you should produce one line of output. This line contains a single integer, which indicates how many almost prime numbers are within the range (inclusive) low…high.

    Sample Input Sample Output
    3
    1 10
    1 20
    1 5
    
    3
    4
    1
    

    Problemsetter: Shahriar Manzoor, special thanks to Derek Kisman

    题目大意:

      这道题说的是,给你一个[l,r],然后让你在这个[l,r]中,找到仅仅含有一个素数因子并且自己不是素数的数的个数。

    解题思路:

      一看题,就知道是数学题,那么我们上来后先打表就是了。

      首先,我们先看看第一组样例[1,10]有3个,那么答案就是4,8,9这三个了?为什么是这三个数字呢?首先4=2*2 = 2^2.仅含有一个素数因子,这个因子是2.

      然后是8 = 2*4 = 2^3也含有一个素数因子,这个因子是2,然后是 9 = 3*3 = 3^2,含有素数因子3。

      不难发现,要想找到自己不是素数,并且仅仅含有一个素因子的数的等价于在这个区间中去寻找是否存在这样的数字val使得对于任意的一个素数p有val = p^i;(i>=2)

      当然,val的值肯定是介于l和r之间的。

      在最初的素数打表的过程中,我们只需要计算出p^2<=10^12   -> p<=10^6.

      所以,只需要计算出[1,10^6]的素数就好了,然后我们从pime[i]*prime[i]开始枚举,直到其数值超过了r为止。。。

    代码:

     1 # include<cstdio>
     2 # include<iostream>
     3 # include<cstring>
     4 
     5 using namespace std;
     6 
     7 typedef long long LL;
     8 
     9 # define MAX 1000004
    10 
    11 LL prime[MAX];
    12 LL book[MAX];
    13 LL len;
    14 
    15 void init()
    16 {
    17     for ( int i = 2;i <= MAX;i++ )
    18     {
    19         book[i] = 1;
    20     }
    21     for ( int i = 2;i <= MAX;i++ )
    22     {
    23         if ( book[i]==1 )
    24         {
    25             for ( int j = 2*i;j <= MAX;j+=i )
    26             {
    27                 book[j] = 0;
    28             }
    29         }
    30     }
    31     for ( int i = 2;i <= MAX;i++ )
    32     {
    33         if ( book[i]==1 )
    34         {
    35             prime[len++] = i;
    36         }
    37     }
    38 
    39 }
    40 
    41 
    42 int main(void)
    43 {
    44     init();
    45     int t;cin>>t;
    46     while ( t-- )
    47     {
    48         LL tot = 0;
    49         LL l,r;
    50         cin>>l>>r;
    51         for ( int i = 0;i < len;i++ )
    52         {
    53             for ( LL j = prime[i]*prime[i];j <= r;j*=prime[i] )
    54             {
    55                 if ( j >= l )
    56                     {
    57                        // cout<<j<<endl;
    58                         tot++;
    59                     }
    60             }
    61 
    62         }
    63         cout<<tot<<endl;
    64 
    65     }
    66 
    67     return 0;
    68 }
  • 相关阅读:
    我的浏览器收藏夹分类
    我的浏览器收藏夹分类
    Java实现 LeetCode 318 最大单词长度乘积
    Java实现 LeetCode 318 最大单词长度乘积
    Java实现 LeetCode 318 最大单词长度乘积
    Java实现 LeetCode 316 去除重复字母
    Java实现 LeetCode 316 去除重复字母
    Java实现 LeetCode 316 去除重复字母
    Java实现 LeetCode 315 计算右侧小于当前元素的个数
    Java实现 LeetCode 315 计算右侧小于当前元素的个数
  • 原文地址:https://www.cnblogs.com/wikioibai/p/4445281.html
Copyright © 2011-2022 走看看