問題の意味:1 <= 1 <R <= 2,147,483,647、Rに最も近い素数と最も遠いを求め、前記隣接する区間[L、R]所与 - L <= 1E6 ..
思考:素数のふるい間隔
最も遠い素数は確か内の[L、R]すべての素数を見つける必要があると[L、R]最近、隣接する見つけることができます。しかし、それはあるかどうかを直接リニアプレイテーブルや暴力は、その多くのデータを処理していません。
表を作成する素数SQRT(r)を与えることができ、合成数で[L、R]にスクリーニングし、次いで素数SQRT(R)とし、[L、R]、記録への答えを横切ります。
1の#include <iostreamの> 2の#include <stdio.hの> 3の#include < 文字列・H> 4 の#defineは長い長いっ 5は、 使用 名前空間STDを、 6 7 のconst int型 MAXN = 1E6 + 10 。 8 CONSTの INT MAX = 1E5。 9 INT プライム[MAX]、タグ[MAX]、VIS [MAXN]、TOT。 10 11 空隙 get_prime(ボイド){ 12 のために(int型 I = 2 ; iは、MAXを<; iは++ ){ 13 もし(!タグ[I]){ 14 プライム[TOT ++] = I。 15 のための(int型 J = 2 ; iは、MAXを<J *; J ++ ){ 16 タグ[j個* I] = 1 。 17 } 18 } 19 } 20 } 21 22 MAX(-1,11,11- b)は{LL 23 リターン A> B?A:B; 24 } 25 26 INTメイン(ボイド){ 27 get_prime()。 28 LLのL、R。 29 一方(〜のscanf(" %のLLDの%のLLD "、&L&R)){ 30 のmemset(VIS、0、はsizeof (VIS))。 31 のためには、(int型 i = 0 ; iはTOT <; iは++ ){ 32 のLL A =(L +プライム[I] - 1)/ プライム[I]。 33 のLL B = R / プライム[I]。 34 のための(int型 J = MAX(2、A); J <= B; J ++){ // 筛[L、R]内的合数 35 VIS [プライム[I] * J - L] = 1。// Lを保存するために再び追加場合便利なラベル、出力回答 36 } 37 } 38は、 IF(1- == 1 VIS)は[ 0 ] = 1 ; // これは素数ではないことに注意してください 39 LL CNT = - 1、SOL1 = MAXN、SOL2 = 0 、X1、Y1、X2、Y2、 40 のために(INT I = 0 ; I <= R&LT - L、Iは++ ){ 41がある IF(VIS [I] == 0 ){ 42で IF(CNT! = - 1 ){ 43が IF(SOL1> I - CNT){ 44れます X1 = CNT; 45の Y1 = I。 46 SOL1 = I - CNT。 47 } 48 であれば(SOL2 <I - CNT){ 49 ×2 = CNT。 50の Y2 = I。 51 SOL2 = I - CNT。 52 } 53 } 54 CNT = I。 55 } 56 } 57 もし(SOL2 == 0)プットは、(" なし隣接素数がありません。" )。 58 他の printf関数(" %のLLD、%のLLDは%LLDが最も離れている、%のLLD最も近い\ nは。"、X1 + L、Y1 + 1、×2 + L、Y2 + 1 リットル); 59 } 60 リターン 0 。 61 }