私の推測問題の解決策

私の推測問題の解決策


【問題の説明】

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");
        }
 }






おすすめ

転載: blog.csdn.net/fdxgcw/article/details/115045039