ZJNU 1223 - 素数距离——高级

因为最大可以达到int极限

明显直接筛选不可能完成

所以从其因子入手

因为任何不是素数的数都有除了1与其自身之外的因子

因此,我们筛出2^(31/2)≈46350之内的所有素数,以其作为因子再将题目给定区间内的所有不是素数的数标记排除

然后将素数存放在prnum这个vector集合中便于调用

在排除阶段,可以用

l=((L+prnum[i]-1)/prnum[i])*prnum[i]

计算出区间内的第一个是prnum[i]的倍数的数

注意,如果计算出来的使其本身,取倍数

再用

r=R/prnum[i]*prnum[i]

计算出最后一个是prnum[i]的倍数的数

符合条件时,从l到r,每次加prnum[i],标记出所有以prnum[i]为因子的数

因为无法直接开数组标记到大数

但又因为R-L≤1000000

所以可以对位置进行转换

标记时取-L+1,取出时取-1+L

最后将区间内的素数取出放在ans这个vector集合内,对答案进行判断即可

(注意特殊情况的判断)

 1 /*
 2 Written By StelaYuri
 3 */
 4 #include<bits/stdc++.h>
 5 using namespace std;
 6 typedef long long ll;
 7 vector<ll> prnum,ans;
 8 bool prim[46400],ar[1000010];
 9 int main(){
10     ll L,R,i,j,cnt,l,r,mxdis,mndis,mxn1,mxn2,mnn1,mnn2,d;
11     scanf("%lld%lld",&L,&R);
12     memset(prim,true,sizeof prim);
13     prim[0]=prim[1]=false;
14     for(i=2;i<=215;i++)
15         if(prim[i])
16             for(j=2*i;j<=46350;j+=i)
17                 prim[j]=false;//埃氏筛法
18     prnum.push_back(2);
19     for(i=3;i<=46349;i+=2)
20         if(prim[i])
21             prnum.push_back(i);//将素数放置在prnum内
22     cnt=prnum.size();
23     memset(ar,true,sizeof ar);
24     if(L==1)
25         ar[1]=false;
26     for(i=0;i<cnt;i++){
27         l=((L+prnum[i]-1)/prnum[i])*prnum[i];
28         if(l==prnum[i])//如果计算得出的l恰好为第i个素数本身,跳过它,取其倍数
29             l+=l;
30         if(l>R)
31             continue;
32         r=R/prnum[i]*prnum[i];
33         for(j=l;j<=r;j+=prnum[i])
34             ar[j-L+1]=false;//标记
35     }
36     for(i=1;i<=R-L+1;i++)
37         if(ar[i])
38             ans.push_back(i-1+L);//将指定区间内的所有素数提出
39     cnt=ans.size();
40     if(cnt<2)
41         puts("There are no adjacent primes.");
42     else{
43         mndis=mxdis=ans[1]-ans[0];
44         mxn1=mnn1=ans[0];
45         mxn2=mnn2=ans[1];
46         for(i=2;i<cnt;i++){
47             d=ans[i]-ans[i-1];
48             if(d>mxdis){
49                 mxdis=d;
50                 mxn1=ans[i-1];
51                 mxn2=ans[i];
52             }
53             if(d<mndis){
54                 mndis=d;
55                 mnn1=ans[i-1];
56                 mnn2=ans[i];
57             }
58         }
59         printf("%lld,%lld are closest, %lld,%lld are most distant.\n",mnn1,mnn2,mxn1,mxn2);
60     }
61
62     return 0;
63 }

原文地址:https://www.cnblogs.com/stelayuri/p/12233657.html

时间: 2024-11-09 00:33:09

ZJNU 1223 - 素数距离——高级的相关文章

素数距离问题

素数距离问题 时间限制:3000 ms  |  内存限制:65535 KB 难度:2 描述 现在给出你一些数,要求你写出一个程序,输出这些整数相邻最近的素数,并输出其相距长度.如果左右有等距离长度素数,则输出左侧的值及相应距离. 如果输入的整数本身就是素数,则输出该素数本身,距离输出0 输入 第一行给出测试数据组数N(0<N<=10000) 接下来的N行每行有一个整数M(0<M<1000000), 输出 每行输出两个整数 A B. 其中A表示离相应测试数据最近的素数,B表示其间的距

nyoj 24 素数距离问题

素数距离问题 时间限制:3000 ms  |            内存限制:65535 KB 难度:2 描述 现在给出你一些数,要求你写出一个程序,输出这些整数相邻最近的素数,并输出其相距长度.如果左右有等距离长度素数,则输出左侧的值及相应距离. 如果输入的整数本身就是素数,则输出该素数本身,距离输出0 输入 第一行给出测试数据组数N(0<N<=10000) 接下来的N行每行有一个整数M(0<M<1000000), 输出 每行输出两个整数 A B. 其中A表示离相应测试数据最近的

南阳oj 语言入门 素数 题目169 素数距离 题目24

 素数  题目169 #include<stdio.h> #include<math.h> int main(){ int prime(int a); int i,j,n,rd,ld,p; scanf("%d",&n); while(n--){ int num,lnum,rnum; scanf("%d",&num); if(num==1){ printf("2\n"); continue; } p=pr

nyoj 素数距离

素数距离问题 时间限制:3000 ms  |  内存限制:65535 KB 难度:2 描述 现在给出你一些数,要求你写出一个程序,输出这些整数相邻最近的素数,并输出其相距长度.如果左右有等距离长度素数,则输出左侧的值及相应距离.如果输入的整数本身就是素数,则输出该素数本身,距离输出0 输入 第一行给出测试数据组数N(0<N<=10000)接下来的N行每行有一个整数M(0<M<1000000), 输出 每行输出两个整数 A B.其中A表示离相应测试数据最近的素数,B表示其间的距离.

NYOJ_24 素数距离问题

题目地址 难度:2. 分析: 本题思想很简单,循环num次,每次输入一个数判断是否是素数,再计算最近的素数和距离. 不过第一遍写完提交AC不了.仔细阅读提示,觉得是边界条件没有考虑清楚. 最后输入测试数据  n= 1  发现输出是 0 1 . 也就是我判断素数的时候没有考虑输入0的情况. 心得: 1.注意边界条件 2.能return就直接return,不要赋值之后再return.见下面分析. #include<iostream> #include<math.h> using nam

nyOJ基础题:素数距离

//一次性全部生成完,想用多少用多少,时间长点#include <iostream> #include<stdio.h> char min(char a, char b){ return (a>b)?b:a;} char max(char a, char b){ return (a>b)?a:b;} void swapIntOrChar(int a, int b){ a^=b^=a^=b;} bool isPrime(int n){ if(n==1) return fa

ZJNU 1205 - 侦探推理——高级

双层枚举嫌疑犯与当日是星期几,统计真话与假话是否满足题意 注意 fake<=N&&fake+neutral>=N 即假话数量不大于N,假话加上没用的废话数量不小于N (注意OJ上的数据存在问题:冒号后跟一个空格,CHARLES的话最后的句号‘.’应为半角,非全角) 1 /* 2 Written By StelaYuri 3 */ 4 #include<bits/stdc++.h> 5 using namespace std; 6 typedef pair<in

ZJNU 1217 - 航线问题——高级

将所有航线的其中一边排序后,另一边进行类dp 定义一个数组c,c[i]表示在所有能够开通i条航线的组合中,位置序号最大的那条航线的序号的最小值 比如下面一个样例 1 3 2 4 3 1 4 2 此时对于航线左边的位置序号已经是排好序的了 那么只需要考虑右边的情况 在所有只开通1条航道的组合中 右侧出现的结果可能是{1},{2},{3},{4} 所以c[1]=1 在所有只开通2条航道的组合中 右侧出现的结果可能是{3,4},{1,2} 这里有两个组合,每个组合位置序号最大的元素分别是4和2,取小

南阳ACM24-素数距离问题

/* 素数距离问题 时间限制:3000 ms  |  内存限制:65535 KB 难度:2 描述 现在给出你一些数,要求你写出一个程序,输出这些整数相邻最近的素数,并输出其相距长度.如果左右 有等距离长度素数,则输出左侧的值及相应距离. 如果输入的整数本身就是素数,则输出该素数本身,距离输出0 输入 第一行给出测试数据组数N(0<N<=10000) 接下来的N行每行有一个整数M(0<M<1000000), 输出 每行输出两个整数 A B. 其中A表示离相应测试数据最近的素数,B表示