最強素數

XLacon發表於2018-09-12

題目表述:
小李在你幫助之下輕鬆戰勝了他的同學們,於是滿懷惡意的同學出了一個題目來為難小李,作為小李神一樣的隊友,你又要出力了。 素數41能寫成連續6個素數之和:41=2+3+5+7+11+13。 現在要求n以內的素數中,能表示為最多連續素數之和的那個數,如果有多個答案,請輸出最大的那個素數。
輸入
僅一行,一個整數n。
輸出
輸出就一個整數,為所求的能表示為最多連續素數和的那個素數。
樣例輸入
100
樣例輸出
41

感悟:
對於演算法的學習,問題的解決,都是一個循序漸進的過程,就像上課,對於今天要講的內容,老師先用有趣相關的東西匯入,然後慢慢的循序漸進的傳授知識點,讓你理解,然後加以大量的練習。其實這個過程和我們自學演算法一樣,很多同學和我一樣,總想著一口吃一個大胖子,不注重學習的循序漸進和基礎練習,允許自己不會,讓自己從最基礎的演算法思維開始學起,這就要求我們多做一些基礎的題,然後不斷的自己分析思維,比如遞迴,遞推,如何一步步的到達了問題的解。剛開始這個過程可能比較慢,有些同學也得不到成就感,因為思維的訓練從來不是立竿見影的,只有經過長期的鍛鍊,才能顯現思維的優勢。

分析:對於此題就是一個訓練基礎思維的好題,拿到題不要慌,在訓練思維階段不求自己有多少創造性發現,只求鍛鍊自己基礎的思維模式,等感覺自己思維訓練的差不多了,自然而然自己就會從原有的思維上進行創造了,這是不矛盾的。只有基礎思維地基打牢了,才有可能進行科學嚴謹的創造發現。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
//#include  <bits/stdc++.h>
using namespace std;

int n;
int ans[1000005];
int primes[1000005];
int v     [1000005];
int res[1000005];
void primed()
{
     int m=0;
    for(int i=2;i<=n;i++)
    {
        if(v[i]==0) {res[i]=1;v[i]=i;primes[m++]=i;}
        for(int j=0;j<m;j++)
        {
            if(primes[j]>v[i]||primes[j]>n/i) break;
            v[primes[j]*i]=primes[j];
        }
    }
}
int main()
{
    cin>>n;
    memset(res,0,sizeof res);
    primed();
    int a=0;
    int max_size=0;
    for(int i=0;;i++) if(primes[i]==0) {a=i-1;break;}
    for(int i=0;i<=a;i++)
    {
        int tem=0;
        for(int j=i;j<=a;j++)
        {
            tem+=primes[j];
            if(tem>n) break;
            if(res[tem])
            {
                max_size=max(max_size,j-i+1);
                ans[j-i+1]=max(tem,ans[j-i+1]);
            }
        }
    }
    cout<<ans[max_size];
    return 0;
}

在此題中要學會的是雙層迴圈交替的探索最長素數和這個思想。

相關文章