看网上题解,告诉我硬暴力可以过,然后我写了一个非常非常暴力的做法,然后tle了
这里附上暴力超时代码:
#include <iostream>
using namespace std;
//首先它本身是不是素数,如果是,那ok,如果不是,那对不起不行
//第二个需要考虑的就是,如果它是素数,除了它本身,还有没有其他的组成手段
//59
//感觉得把素数存起来,
const int maxn = 1e4+10;
long long isprime[maxn];
int top;
int isPrime(long long x)
{
int ret = 1;
int i;
if( x == 1 || (x%2 == 0 && x!=2 )){
ret=0;
}
for(int i=3;i<x;i+=2){
if( x % i == 0){
ret = 0;
break;
}
}
return ret;
}
long long n,ans,sum;
int main() {
top=0;
for(long long i=2;i<=maxn;i++){
if(isPrime(i)!=0){
isprime[top++]=i;
}
}
while(scanf("%lld",&n)!=EOF){
if(n==0) break;
ans=0;
//判断一下这玩意是不是素数,是的话怎么操作,不是的话怎么操作
if(isPrime(n)==0){
ans = 0;
}
else{
for(int m=0;m<n;m++){
sum=0;
for(int q=m;q<n;q++){
sum+=isprime[q];
if(sum==n){
ans++;
break;
}
}
}
}
printf("%lld\n",ans);
}
return 0;
}
然后我把求素数的方法优化了一下,加了一个sqrt()
最后,我把枚举判断变成了尺取法,但其实就是双指针
#include <iostream>
#include<cmath>
using namespace std;
//首先它本身是不是素数,如果是,那ok,如果不是,那对不起不行
//第二个需要考虑的就是,如果它是素数,除了它本身,还有没有其他的组成手段
//59
//感觉得把素数存起来,
const int maxn = 1e4+10;
long long isprime[maxn],presum[maxn];
int top;
int isPrime(int x)
{
int ret = 1;
int i;
if( x == 1 || (x%2 == 0 && x!=2 )){
ret=0;
}
int m = sqrt((double)x);
for(int i=3;i<=m;i+=2){
if( x % i == 0){
ret = 0;
break;
}
}
return ret;
}
long long n,ans,sum;
int main() {
top=0;
presum[0]=0;
for(long long i=2;i<=maxn;i++){
if(isPrime(i)!=0){
isprime[++top]=i;
// printf("%lld\n",isprime[top-1]);
}
}
for(int i=1;i<=top;i++){
presum[i]=presum[i-1]+isprime[i];
// printf("%lld\n",presum[i]);
}
while(scanf("%lld",&n)!=EOF){
if(n==0) break;
ans=0;
int l,r;
for(l=r=0;r!=n/*||presum[r]-presum[l]<=n*/;){
if(presum[r]-presum[l]==n){
ans++;l++;
}
else if(presum[r]-presum[l]>n) l++;
else if(presum[r]-presum[l]<n) r++;
}
//判断一下这玩意是不是素数,是的话怎么操作,不是的话怎么操作
// for(int m=0;m<n;m++){
// sum=0;
// for(int q=m;q<n;q++){
// sum+=isprime[q];
// if(sum==n){
// ans++;
// break;
// }
// }
// }
printf("%lld\n",ans);
}
return 0;
}
然后过了
思路就是先得到一个素数表,然后再双指针暴力。