1716: Divisors(素数筛选)

本文介绍了一种高效算法,用于找出指定范围内拥有最多除数的整数及其除数数量。通过筛选法预先处理素数,并利用优化技巧确保算法能在短时间内处理大范围的数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 


StatusIn/OutTIME LimitMEMORY LimitSubmit TimesSolved UsersJUDGE TYPE
stdin/stdout3s8192K266100Standard

Mathematicians love all sorts of odd properties of numbers. For instance, they consider 945 to be an interesting number, since it is the first odd number for which the sum of its divisors is larger than the number itself.

 

To help them search for interesting numbers, you are to write a program that scans a range of numbers and determines the number that has the largest number of divisors in the range. Unfortunately, the size of the numbers, and the size of the range is such that a too simple-minded approach may take too much time to run. So make sure that your algorithm is clever enough to cope with the largest possible range in just a few seconds.

Input Specification

The first line of input specifies the number N of ranges, and each of the N following lines contains a range, consisting of a lower bound L and an upper bound U, where L and U are included in the range. L and U are chosen such that and .

Output Specification

For each range, find the number P which has the largest number of divisors (if several numbers tie for first place, select the lowest), and the number of positive divisors D of P (where P is included as a divisor). Print the text 'Between L and H, P has a maximum of D divisors.', where L, H, P, and D are the numbers as defined above.

Example input

 

3
1 10
1000 1000
999999900 1000000000

Example output

 

Between 1 and 10, 6 has a maximum of 4 divisors.
Between 1000 and 1000, 1000 has a maximum of 16 divisors.
Between 999999900 and 1000000000, 999999924 has a maximum of 192 divisors.

 

 


Submit / Problem List / Status / Discuss

 

所谓有素数筛选法,就是从2(最小的素数)开始往上进行筛选,把所有质数的整倍数都剔除掉,最后剩下来的就是素数了。当然这不是最好最快的方法,占用的空间也不小,不过这种方法简单易行,运行效率也不是太低——比起最普通的用函数判断每个数那也是天壤之别了,所以还是非常常用的。

有一处优化:筛选i的倍数时,可以直接从i^2开始筛选,因为比i^2小的倍数已经被比i小的素数给筛选掉了,因为这样,外层循环也可以只累加到sqrt(n)即可。另外一个Re_storage函数将素数表进行转存,便于某些情况下的访问,prime_count保存素数的个数

 

#include<iostream>
#include<math.h>
#define maxn 1000000000;
bool isprime[32000];
int prime[15000],num[15000];
int prime_count;
void Make()
{
       int i,j;
       memset(isprime,true,sizeof(isprime));
       isprime[0] = isprime[1] = false;
       for (i=2;i<180;i++)
    {
              if(isprime[i])
     {
                     for(j=i*i;j<32000;j+=i)
                            isprime[j]=false;
              }
       }
}
void Re_storage ()
{
       prime_count=0;
       for (int i=2;i<32000;i++)
    {
              if(isprime[i])
                    prime[prime_count++]=i ;
       }
}
int main()
{
 freopen("in.txt","r",stdin);
 freopen("out.txt","w",stdout);
 int n,i,j,l,u,count,m;
 int max,k,k2;
 Make();
 Re_storage();
 scanf("%d",&n);
 while(n--)
 {
  max=-1;
  scanf("%d%d",&l,&u);
  for(i=l;i<=u;i++)
  {
     memset(num,0,sizeof(num));
     int x=(int)sqrt(i);
     count=0;
     m=i;
     for(j=0;prime[j]<=x;j++)    
   {     
    if(i%prime[j]!=0)continue;     
    while(m%prime[j]==0)     
    {      
     num[count]++;      
     m/=prime[j];     
    }     
    count++;     
    if(m==1)break;    
   } 
     if(m>1)
    num[count++]=1;
     k2=1;
     for(j=0;j<count;j++)
         k2=k2*(num[j]+1);
        if(max<k2)
        {
    max=k2;
    k=i;
     }  
  }
   printf("Between %d and %d, %d has a maximum of %d divisors./n",l,u,k,max);
 }
 return 0;
}

以下是代码要求和代码,代码要求:在命令行界面提示用户输入正整数n(2<=n<=1000),找出不超过n的所有素数的集合,并按照10个一行进行格式化输出,输出的素数之间用逗号隔开,每一个素数占位4字符,不够4字符的用空格补齐。代码:/* Copyright© 2025 Shenzhen TP-LINK Technologies Co.Ltd. file work2.c brief This is a sample of coding criterion for prime checking. author Lin Zihao version 1.0.1 date 25Jul31 history \arg 1.0.1, 25Jul31, Lin Zihao, Create the file. */ #include <stdio.h> // /* DEFINES */ // #define MAX_RANGE 1000 /* 定义用户输入的最大范围 / #define MIN_RANGE 2 / 定义用户输入的最小范围 */ // /* TYPES */ // // /* EXTERN_PROTOTYPES */ // // /* LOCAL_PROTOTYPES */ // static int is_prime(int x); // /* VARIABLES */ // // /* LOCAL_FUNCTIONS */ // /* Function: is_prime Purpose: Checks whether a given integer is a prime number。 Parameters: n - The integer to be checked Return value: Returns 1 if the number is prime, 0 otherwise. / int is_prime(int x) { if (x <= 1) return 0; / Numbers less than 2 are not prime / for (int i = 2; ii<=x; i++) { /* Check only odd numbers up to n-1 / if (0 == x % i) return 0; / If divisible by any odd number, it’s not prime / } return 1; / If no divisors found, the number is prime */ } // /* PUBLIC_FUNCTIONS */ // // /* GLOBAL_FUNCTIONS */ // /* Function: main Purpose: Entry point of the program. Demonstrates the use of the is_prime function. Parameters: n - Represents the upper limit of the range within which the program identifies. dentifies. count - An integer counter used to manage the formatting of the output. Return value: 0 on successful execution, non-zero otherwise. Notes: This function is for demonstration purposes only. */ int main() { int n, count = 0; // Define variables: n for user input limit, count for tracking output formatting printf(“Enter a positive integer n:); scanf(”%d”, &n); if(n <MIN_RANGE || n>MAX_RANGE){ /* Validate input range */ printf("Error!Please enter a number between 2 and 1000."); }else{ printf("Prime numbers up to %d are:\n", n); for (int i = 2; i <= n; i++) { if (is_prime(i)) { if (0 == count % 10 && 0 != count) { /* Start a new line after every 10 primes */ printf("\n"); } if (0 != count % 10) { /* Add comma separator except before the first number in a line */ printf(", "); } printf("%4d", i); /* Print prime number with 4-character width formatting */ count++; } } printf("\n"); } return 0; } 现在要写一个程序设计概要,目前已有初稿,现在请你修改润色下,写的更加详细深入些,并在概要设计中给出以下几个问题的回答:1、如何让用户使用起来更友好?2、如果n的输入范围【2,1000】发生变化,那任务性质会随之发生什么变化?3、考虑嵌入式环境,如何提高效率?程序效率和通用性的关系是怎样?——以下是初稿:2. 素数输出 2.1. 前言 2.1.1. 项目简要说明 实现素数筛选和格式化输出功能,输入正整数n(2≤n≤1000),输出所有不超过n的素数。 2.1.2. 任务概述 数学计算模块,需优化素数判断算法。 2.2. 需求分析 2.2.1. 功能需求 输入验证:2≤n≤1000 素数判断:识别不超过n的所有素数 格式化输出: 每行10个素数 逗号分隔 固定4字符宽度(右对齐) 2.3. 代码设计
最新发布
08-07
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值