Prime Friend
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3325 Accepted Submission(s): 673
Problem Description
Besides the ordinary Boy Friend and Girl Friend, here we define a more academic kind of friend: Prime Friend. We call a nonnegative integer A is the integer B’s Prime Friend when the sum of A and B is a prime.
So an integer has many prime friends, for example, 1 has infinite prime friends: 1, 2, 4, 6, 10 and so on. This problem is very simple, given two integers A and B, find the minimum common prime friend which will make them not only become primes but also prime neighbor. We say C and D is prime neighbor only when both of them are primes and integer(s) between them is/are not.
So an integer has many prime friends, for example, 1 has infinite prime friends: 1, 2, 4, 6, 10 and so on. This problem is very simple, given two integers A and B, find the minimum common prime friend which will make them not only become primes but also prime neighbor. We say C and D is prime neighbor only when both of them are primes and integer(s) between them is/are not.
Input
The first line contains a single integer T, indicating the number of test cases.
Each test case only contains two integers A and B.
Technical Specification
1. 1 <= T <= 1000
2. 1 <= A, B <= 150
Each test case only contains two integers A and B.
Technical Specification
1. 1 <= T <= 1000
2. 1 <= A, B <= 150
Output
For each test case, output the case number first, then the minimum common prime friend of A and B, if not such number exists, output -1.
Sample Input
2 2 4 3 6
Sample Output
Case 1: 1 Case 2: -1
Author
iSea@WHU
Source
题意:给两个数m,n,求使m,n加上一个数后变成两个相邻数素数的最小数
时间限制是2S,可以直接暴力求解,问题是素数打表范围该怎么考虑,因为m,n<=150,打表范围应该到任意m-n(m-n为偶数,1除外)都能找到对应的两个素数差值等于m-n
可以暴力打表先找一找规律
void prime()
{
p[0]=0;
mem(vis,0);
mem(num,0);
for(int i=2;i<=Max;i++)
{
if(!vis[i])p[++p[0]]=i;
for(int j=1;j<=p[0]&&(ll)i*p[j]<=Max;j++)
{
vis[i*p[j]]=1;
if(!(i%p[j]))break;
}
}
for(int i=1;i<p[0];i++)
{
int o=p[i+1]-p[i];
num[o]++;
}
for(int i=0;i<=150;i++)
pf("%d ",num[i]);
}
若打表到1e7,在后面的只里面仍然有几个连续为0(无法满足条件),打表范围到2e7时,偶数位(加上1)全部不为0,这时就满足条件了
暴力的方式有两种,一种是直接枚举所有相邻素数,求出最小的那个即可
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
#include<stack>
#include<queue>
#include<deque>
#include<set>
#include<map>
#include<cmath>
#include<vector>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> PII;
#define pi acos(-1.0)
#define eps 1e-10
#define pf printf
#define sf scanf
#define lson rt<<1,l,m
#define rson rt<<1|1,m+1,r
#define e tree[rt]
#define _s second
#define _f first
#define all(x) (x).begin,(x).end
#define mem(i,a) memset(i,a,sizeof i)
#define for0(i,a) for(int (i)=0;(i)<(a);(i)++)
#define for1(i,a) for(int (i)=1;(i)<=(a);(i)++)
#define mi ((l+r)>>1)
#define sqr(x) ((x)*(x))
const int inf=0x3f3f3f3f;
const int Max=2e7+1;
int t,m,n,p[Max/10];
bool vis[Max+1];
void prime()
{
p[0]=0;
mem(vis,0);
for(int i=2;i<=Max;i++)
{
if(!vis[i])p[++p[0]]=i;
for(int j=1;j<=p[0]&&(ll)i*p[j]<=Max;j++)
{
vis[i*p[j]]=1;
if(!(i%p[j]))break;
}
}
}
int main()
{
prime();
sf("%d",&t);
for1(i,t)
{
sf("%d%d",&m,&n);
pf("Case %d: ",i);
if(m>n)swap(m,n);
int ans=-1;
for(int i=2;i<=p[0];i++)
if(p[i]-n>=0&&p[i-1]-m>=0)
if(p[i]-n==p[i-1]-m)
{
ans=p[i]-n;
break;
}
pf("%d\n",ans);
}
return 0;
}
时间为1300MS比较慢
因为1-150最大差值才149,在素数打表后预处理一下就行,再枚举的话会快很多
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
#include<stack>
#include<queue>
#include<deque>
#include<set>
#include<map>
#include<cmath>
#include<vector>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> PII;
#define pi acos(-1.0)
#define eps 1e-10
#define pf printf
#define sf scanf
#define lson rt<<1,l,m
#define rson rt<<1|1,m+1,r
#define e tree[rt]
#define _s second
#define _f first
#define all(x) (x).begin,(x).end
#define mem(i,a) memset(i,a,sizeof i)
#define for0(i,a) for(int (i)=0;(i)<(a);(i)++)
#define for1(i,a) for(int (i)=1;(i)<=(a);(i)++)
#define mi ((l+r)>>1)
#define sqr(x) ((x)*(x))
const int inf=0x3f3f3f3f;
const int Max=2e7+1;
bool vis[Max+1];
int p[Max/10],num[200],pos[200][200],t,m,n;
void prime()
{
p[0]=0;
mem(vis,0);
mem(num,0);
for(int i=2;i<=Max;i++)
{
if(!vis[i])p[++p[0]]=i;
for(int j=1;j<=p[0]&&(ll)i*p[j]<=Max;j++)
{
vis[i*p[j]]=1;
if(!(i%p[j]))break;
}
}
for(int i=1;i<p[0];i++)
{
int o=p[i+1]-p[i];
if(o<=150&&num[o]<200)//不需要计算出那么多的素数,一个差值对应200个已经足够了
pos[o][num[o]++]=p[i];
}
}
int main()
{
prime();
sf("%d",&t);
for1(i,t)
{
sf("%d%d",&m,&n);
if(m>n)swap(m,n);
int k=n-m;
int ans=-1;
for(int i=0;i<num[k];i++)
if(pos[k][i]>=m)
{
ans=pos[k][i]-m;
break;
}
pf("Case %d: %d\n",i,ans);
}
return 0;
}