1. 程式人生 > >QDU-GZS與素數大法(素數篩法)

QDU-GZS與素數大法(素數篩法)

Description

 

自從GZS成為G神之後,追隨者不計其數,更是有了大名鼎鼎的拜神論:

"吾嘗終日程式設計也,不如須臾之拜拜G神也;吾嘗打字刷題也,不如一日三拜G神也;

拜拜G神,程式非長也,而出結果;三拜G神,打字非快也,而能AC。

吾日三拜G神也!!!“

作為菜鳥,經常遇到一些難題,於是就去拜見G神了。G神一看題目,微微一笑說道:“這種水題也算難題?我閉著眼都能一分鐘刷十道!”畢竟是G神,我等菜鳥還是得虛心向G神學習。各位大神們,相信這道水題你們也能很快就AC吧。題目是這樣的:

 

給定一個範圍[l,r],求[l, r]中的距離最近的兩個相鄰素數和距離最遠的兩個相鄰素數。

Input

 

多組測試資料,每組資料一行,包含兩個數字l和r。1<=l<=r<=5*10^6。

Output

 

如果存在,則按樣例格式輸出最近的兩個素數和最遠的兩個素數(如果有多個,輸出最小的);如果不存在,輸出一行:There are no adjacent primes.

Sample Input 1 

2 17
14 17

Sample Output 1

2,3 are closest, 7,11 are most distant.
There are no adjacent primes.

Source

qduoj 第一次月賽 for 2014級

思路:用尤拉篩法先篩出素數,然後遍歷兩次找出最大的和最小的,注意1既不是素數也不是合數

程式碼:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cmath>

using namespace std;
int prime[5000005];
bool vis[5000006];
void oula() {
	int cnt=0;
	memset(prime,0,sizeof(prime));
	memset(vis,false,sizeof(vis));
	for(int t=2; t<=5000005; t++) {
		if(!vis[t])
			prime[cnt++]=t;
		for(int j=0; j<cnt&&t*prime[j]<=5000005; j++) {
			vis[t*prime[j]]=true;
			if(t%prime[j]==0)
				break;
		}
	}
}

int a[5000005];
int b[5000005];

int main()
{
	
	int l,r;
	int k;
	int k2;
	oula();
	vis[1]=true;
	while(cin>>l>>r)
	{
		k=0;
		k2=0;
		for(int t=l;t<=r;t++)
		{
			if(vis[t]==false)
		    {
			a[k++]=t;
		    }
		    
	    }
	   
	    for(int t=1;t<k;t++)
	    {
	         b[k2++]=a[t]-a[t-1];	
		}
		sort(b,b+k2);
		int s1,s2,s3,s4;
		for(int t=1;t<k;t++)
		{
			if(a[t]-a[t-1]==b[0])
			{
				s1=a[t-1];
				s2=a[t];
				break;
			}
		}
		for(int t=1;t<k;t++)
		{
			if(a[t]-a[t-1]==b[k2-1])
			{
				s3=a[t-1];
				s4=a[t];
				break;
			}
		}
		if(k>1)
		cout<<s1<<","<<s2<<" are closest, "<<s3<<","<<s4<<" are most distant."<<endl;
		else
		{
			cout<<"There are no adjacent primes."<<endl;
		}
	}
	
	
	return 0;
 }