私の推測問題の解決策
【問題の説明】
1742年、ドイツの数学者ゴールドバッハは有名なゴールドバッハの予想を提案しました。4以上の偶数は、2つの素数の合計として表すことができます。この推測はまだ完全に正しいことが証明されていません。
ただし、5以上の奇数の場合、2つの素数の合計として表現できるものと、表現できないものがあります。5以上の奇数が与えられた場合、それを2つの素数の合計に分解できるかどうかを判断します。
【入力フォーム】
入力には複数のテストデータが含まれ、各テストデータは1行を占め、正の整数m、mは奇数、5以上32767以下です。
【出力形式】
各検定データについて、mを2つの素数の和に分解できる場合はyesを出力し、そうでない場合はnoを出力します。
【サンプル入力】
21
75
99
113
【サンプル出力】
はい
はい
はい
番号
質問の意味は非常に単純です。それは、数を2つの素数に分割できるかどうかを判断することです。
入力タイプは常にファイルの最後に入力されるため、入力にはwhile(cin >> n)メソッドを使用します。最初に
暴力的なアルゴリズムを見てください。時間計算量はO(n ^ 3)です
(この複雑さを見るだけで、GGが必要であることがわかります)
#include<iostream>
using namespace std;
int n;
bool judge(int x)//判断是否为素数
{
if(x==2)return true;
for(int i=2;i<x;i++)
{
if(x%i==0)return false;
}
return true;
}
bool check(int a)
{
for(int i=2;i<a/2;i++)//枚举每一种组合
{
if(judge(i)&&judge(a-i))return true;//只要有一种组合成立,命题成立
}
return false;
}
int main()
{
while(cin>>n)
{
if(check(n))cout<<"yes"<<endl;
else cout<<"no"<<endl;
}
}
もちろん、暴力は許されていません(少なくともアルゴリズムの問題であり、暴力と戦う機会はありません)ので、前学期の暴力との戦い
の考え方を片付けるように生徒に依頼してください。
最適化1数論の知識
数学Konjacは何かを証明するためにバラバラに来るのが恥ずかしいです、結論を投げてください:
奇数が2に分割され、別の数が両方の数が素数である場合、この数は2に分割できます組み合わせ素数の数、またはその逆。率直に
言って、 n-2が素数であるかどうかを判断するだけです。
このようにして、ループの層を省略でき、複雑さはO(n ^ 2)に最適化されます。
#include<iostream>
using namespace std;
int n;
bool judge(int x)//判断是否为素数
{
if(x==2)return true;
for(int i=2;i<x;i++)
{
if(x%i==0)return false;
}
return true;
}
bool check(int a)
{
if(judge(2)&&judge(a-2))return true;//只要有一种组合成立,命题成立
return false;
}
int main()
{
while(cin>>n)
{
if(check(n))cout<<"yes"<<endl;
else cout<<"no"<<endl;
}
}
ループの1つのレベルを最適化した後、それは1に正常に圧縮されました。
それで、問題は、それを少し最適化できるかということです。
最適化2ふるい素数+テーブルヒットテーブルヒット
について説明します。テーブルヒットは、ある種のアルゴリズムの総称です。プログラムが正式に実行される前に、事前にデータを大まかに計算します。たとえば、この質問の場合、最大テストデータはわずか32767です。32800より前のすべての素数を最初に計算できます。
2つ目は、この質問を入力する方法であるふるい素数です。従来の品質判定方法を使用すると、プログラムが終了する前に時計がカットされる場合があります。
ふるい素数は、特定の数の倍数を列挙し、1を除くすべての倍数をふるいにかけ、残りはすべて素数です。
例えば、素数を計算
から1 20に2の倍数のうちふるい
4、
6、8、10 、12、14、16、18、20倍うちふるい3 6、9、12、15、18のふるいアウト5の倍数
10、15のふるい分け7、14の7の倍数
。。。。。。。。。。
ふるいの終わりには、1(切り捨て)、2、3、5、7、11、13、17、19のみです。
このようにして、素数を計算できます。
トラブルを恐れていない場合は、これらの素数をコードに書き込むこともできます。これは、
O(n)
Wuhuが離陸するクロッキングのリアルタイムの複雑さです。
#include<iostream>
using namespace std;
int m;
const int N=32800;
int a[N];
void build()//算素数
{
for(int i=2;i<N/2;i++)
{
if(!a[i])
for(int j=2;j*i<N;j++)
{
a[j*i]=1;
}
}
}
bool check(int x)
{
if(!a[x-2])return true;
return false;
}
int main()
{
build();
while((scanf("%d",&m))!=EOF)
{
if(check(m))printf("yes\n");
else printf("no\n");
}
}