一个朴素的想法是:1.先得到n以内的素数 2.两重循环枚举A+B , 判断是否是某个素数的平方。
对于第一步,n=5e5 , 需要使用素数筛来加速这个过程。直接暴力判素数O(nn)会超时。可以使用埃式筛得到。
对于第二步,我们从第一步得到素数为4e4数量级。所以无法直接O(p2)的作循环。但我们观察到这样的对其实很少!
因为A+B=C2 , 那么也就要求C不能太大,C=A+B≤2∗4e4=282 。 那么[1,282] 内的素数就非常稀少了。
所以我们可以先用哈希H存储所有素数。然后先枚举C , 再枚举A 。然后再H 中查找B的存在。
# Read the input
n = int(input())
# Sieve of Eratosthenes to find prime numbers up to n
is_prime = [True] * (n + 1)
is_prime[0] = is_prime[1] = False
primes = []
for i in range(2, n + 1):
if is_prime[i]:
primes.append(i)
for j in range(2 * i, n + 1, i):
is_prime[j] = False
# Use a set for faster lookups
s = set(primes)
# Count the pairs
cnt = 0
for i in range(len(primes)):
x = primes[i] ** 2
if x >= primes[-1] * 2:
break
for j in range(len(primes)):
y = x - primes[j]
if y in s:
cnt += 1
break
# Print the count
print(cnt)
import java.util.*;
class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
boolean[] st = new boolean[n+1];
List<Integer> list = new ArrayList<>(); // 素数
for(int i = 2;i <= n;i++){
if(st[i]) continue;
list.add(i);
for(int j = i;j <= n;j += i){
st[j] = true;
}
}
// C枚举,复杂度根号n
int ans = 0;
Set<Integer> set = new HashSet<>(list);
for(int i = 0;i < list.size();i++){
long total = 1L * list.get(i) * list.get(i);
if(total > 1L * 2 * list.get(list.size()-1)){
break;
}
for(int j = 0;j < list.size();j++){
long diff = total - 1L * list.get(j);
// System.out.println(total+" "+diff);
if(set.contains((int)diff)){
ans++;
}
}
}
System.out.println(ans);
}
}
#include <bits/stdc++.h>
#include<string>
using namespace std;
const int maxn=5e5+10;
typedef long long ll;
const ll inf=1e9+7;
const ll mod=1e9+7;
//线性筛
int prime[maxn];
bool vis[maxn];
map<int,bool>mp;
int tot;
void get_prime(int n){
for(int i=2;i<=n;++i){
if(!vis[i]){
prime[++tot]=i;
vis[i]=1;
mp[i]=1;
}
for(int j=1;i*prime[j]<=n;++j){
vis[i*prime[j]]=1;
if(i%prime[j]==0)break;
}
}
}
int main()
{
ios::sync_with_stdio(false);
int N;
cin>>N;
get_prime(500000);
int ans=0;
set<int>::iterator it;
for(int i=1;i<=tot;++i){
int C=prime[i];
if(C*C>N+1)break;
for(int j=1;j<=tot;++j){
int A=prime[j];
if(A>=C*C)break;
int B=C*C-A;
if(mp[B])ans++;
}
}
cout<<ans<<endl;
return 0;
}
小红希望你找出满足A+B=C2,且A,B,C均小于等于N的素数三元组(A,B,C)的数量。
素数三元组:A,B,C都是素数。
输入的第一行给出正整数N。
1<=N<=5∗105
一行中输出答案。
输入
8
输出
3
说明
2,2,2
7,2,3
2,7,3