ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Prosti

2022-07-25 18:04:00  阅读:137  来源: 互联网

标签:const int 质数 Prosti wh while getchar


link

蒟蒻只会打表。

由于题目中 \(K\) 和 \(M\) 都很小,那么我们可以考虑找出一个长度为 \(K\) 的区间满足其中刚好有 \(L\) 个质数,保存下来到时候输出即可。给出打表程序的代码,代码中有注释:

#include<bits/stdc++.h>
#define feyn
const int N=10001000;
const int S=1e7-200; 
const int M=200;
using namespace std;
inline void read(int &wh){
    wh=0;int f=1;char w=getchar();
    while(w<'0'||w>'9'){if(w=='-')f=-1;w=getchar();}
    while(w<='9'&&w>='0'){wh=wh*10+w-'0';w=getchar();}
    wh*=f;return;
}

int p[N/3],sum[N],cnt,ans[M][M];
bool s[N];

signed main(){
	
	#ifdef feyn
	freopen("out.txt","w",stdout);
	#endif
	
	for(int i=2;i<N;i++){
		sum[i]=sum[i-1];
		if(s[i]==false)p[++cnt]=i,sum[i]++;
		for(int j=1;j<=cnt;j++){
			if(i*p[j]>=N)break;
			s[i*p[j]]=true;
			if(i%p[j]==0)break;
		}
	}
	//线性筛并对质数的数量求前缀和(sum[i]表示[1,i]中质数个数) 
	
	//ans[i][j]代表长度为i的、区间内有j个质数的一种可能的方案 
	for(int i=2;i<N;i++){
		for(int j=1;j<=i&&j<=150;j++){
			//j:区间长度 
			int now=sum[i]-sum[i-j];
			if(i-j+1<=S)ans[j][now]=i-j+1; 
		}
	}
	
	//输出 
	printf("{");
	for(int i=1;i<=150;i++){
		printf("{");
		for(int j=0;j<=i;j++){
			if(ans[i][j]){
				if(j!=0)printf(",");
				printf("%d",ans[i][j]);
			}
			//如果方案不存在则不输出,否则会超出代码长度限制 
		}
		printf("},");
	}
	
	return 0;
}

上述程序需要运行两三秒的样子。然后考虑如何求得答案。明显答案可能有两种情况,一种是答案对应的区间和区间 \([1,M]\) 有交集,这部分可以暴力枚举验证;另一种是没有交集,这部分的答案等价于求定长区间内恰好有 \(L\) 个质数的方案,直接输出保存的答案即可。

#include<bits/stdc++.h>
//#define feyn
const int N=200; 
using namespace std;
inline void read(int &wh){
    wh=0;int f=1;char w=getchar();
    while(w<'0'||w>'9'){if(w=='-')f=-1;w=getchar();}
    while(w<='9'&&w>='0'){wh=wh*10+w-'0';w=getchar();}
    wh*=f;return;
}

int ans[N][N]=;//刚才程序输出的东西 
 
inline bool p(int wh){
	if(wh<2)return false;
	for(int i=2;i*i<=wh;i++){
		if(wh%i==0)return false;
	}
	return true;
}
int sum[N<<2];

signed main(){
	
	#ifdef feyn
	freopen("in.txt","r",stdin);
	#endif
	
	int m,a,b,c;
	read(m);
	while(m--){
		read(a);read(b);read(c);
		bool ok=false;
		memset(sum,0,sizeof(sum));
		for(int i=1;i<=(a+c)*2;i++){
			sum[i]=sum[i-1];
			if(i<=c||p(i))sum[i]++;
		}
		for(int i=a;i<=(a+c)*2;i++){
			if(sum[i]-sum[i-a]==b){
				ok=true;
				printf("%d\n",i-a+1);
				break;
			}
		}
		//以上代码对应第一种决策 
		if(ok)continue;
		printf("%d\n",(ans[a][b]==0||ans[a][b]<=c)?-1:ans[a][b]);
		//如果第一种不行那么找第二种 
	}
	
	return 0;
}

当然呢,打表是万不得已的方法,能写正解还是写正解比较好。

标签:const,int,质数,Prosti,wh,while,getchar
来源: https://www.cnblogs.com/dai-se-can-tian/p/16518230.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有