poj2262

3576 ワード

要旨:本題は難しくないが、時間の制限に注意しなければならない。基本的な考え方は必ず両側から中間にスキャンを開始することで、得られる素数の差が最大になることを確保することができる.しかし、それだけでは時間テストには通じない。他の人のコードを参考にして、理論上の時間界は同じであるにもかかわらず、実践の中で速度を高めることができることを発見した。


改善:isprimeというカスタム関数を使ったため、大きな数をテストすると、そのオーバーヘッドが大きい。我々はできるだけ大きな数を減らす検査を行うべきである。3から始まる素数で検査を開始すれば、N-minprimeが素数であるかどうかを検査するだけでよい.両方の素数(minprimeとmaxprime)を同時に検出する場合に注意してください。大まかな費用を分析してみましょう。初期のmin+max>N.を仮定すると、私たちのプログラムはmaxprimeを減らすことを選択します。このとき、減らすたびにisprimeを呼び出して大きな数をチェックします。この時の出費は大きい。もし私たちがminprimeだけを大きくすることを採用したら、注意して、私たちは次のminprimeを計算した後にmaxprimeを検査して、総計算回数は多くないはずです(あるいは同じですか?)しかし、minprimeを計算する回数はmaxprimeより多くなり、オーバーヘッドの低減に成功する.

#include "stdafx.h"
#include "iostream"
using namespace std;
int isprime(int N)
{
    if(N%2 == 0&&N!=2)
        return 0;
    for (int i = 3;i*i <=N;i+=2)
    {
        if(N%i==0)
            return 0;
    }
    return 1;
}

int  main()
{
    int minprime ,maxprime,N;
    while(1)
  {
        cin>>N;
        if(N==0)
        break;
   minprime = 3,maxprime = N - 3;
   maxprime = (maxprime%2==0)?maxprime-1:maxprime;// max , 1 ( )
   while(minprime<=N/2)
   {
       while(!isprime(minprime))// 
           minprime+=2;
       if(isprime(N-minprime))
       {
           cout<<N<<" = "<<minprime<<" + "<<N-minprime<<endl;
           break;
       }
       minprime +=2;
   }
}
    return 0;
}