Zadanie z hipotezą Goldbacha

0

Treść zadania to:

Liczba Goldbacha jest to taka liczba naturalna, którą można zapisać przy pomocy
dwóch liczb pierwszych np. 8, bo 8=3+5.
Napisz program, który wypisze wszystkie liczby Goldbacha (najlepiej z rozkładem np.
102=31+71) nie większe niż n (podawane przez użytkownika).
Podpowiedzi:
• wykorzystaj funkcję „czy_pierwsza” omawianą na poprzedniej lekcji.
• jeżeli któraś liczba Goldbacha ma kilka różnych sposobów rozkładu, to wypisz
tylko jeden

Mój problem polega na tym, że stworzyłem program, który potrafi znaleźć te liczby ale nie jestem w stanie wymyślić jak zaradzić drugiej kropce czyli żeby te same sumy działań różnych liczb pierwszych wyświetlały się jednokrotnie nie wiele razy. Siedzę nad tym już ponad dwie godziny będę wdzięczny za wszelką pomoc.

Tak wygląda kod:

#include <iostream>
#include <math.h>
using namespace std;

bool pierwsza(int n);
bool pierwsza1(int n);

//=====================================================
int main()
{
	int n,suma=0;
	
	cin>>n;
	
	for(int i=2; i<n; i++)
	{	
	if(pierwsza(i)==1)	
	{
		for(int j=2; j<n; j++)
		{	
			if(pierwsza1(j)==1)
			{
				if(i+j<=n)
				{					
					
					suma=i+j;								
					cout<<i<<"+"<<j<<"="<<suma;
					cout<<endl;
				}
				}									
			}
		}			
	}
	
return 0;	    
	}
//=====================================================
bool pierwsza(int n)
{
	for(int i=2;i<=sqrt(n);i++)	
	{
		if(n%i==0)
		{
			return false;
		}
	}	
	return true;
}
//=====================================================
bool pierwsza1(int n)
{
	for(int i=2;i<=sqrt(n);i++)	
	{
		if(n%i==0)
		{
			return false;
		}
	}	
	return true;
}
//=====================================================
1

Albo podejdź do problemu odwrotnie - szukaj takiej pary liczb dla każdej kolejnej liczby i ją (tę parę) wypisuj jak ją znajdziesz, albo zapisuj wyniki do zbioru (np. std::map), w którym będziesz przechowywał tylko jedną parę dla danej wartości.

1

A nie można przerwać wewnętrznej pętli po wypisaniu?

1

Nie w tym rozwiązaniu, bo on tu np. po 2+3=5 wypisze 2+5=7, czyli różne liczby.

2

To troszke inaczej powinno iść (acha i Miałeś błąd w sprawdzaniu pierwszości):

#include <iostream>
#include <math.h>
using namespace std;

bool pierwsza(int n);

int main()
{
    int n;

    cin>>n;

    for(int i=4; i<n; i++)
    {   
    
        for(int j=2; j<=i; j++)
        {   
            if(pierwsza(j) && pierwsza(i - j))
            {          
                cout<< i <<" "<< j<<" " << i - j<< "\n";
                break;
            }                                   
        }
               
    }

    return 0;       
}

bool pierwsza(int n)
{       
    if (n < 4) return n > 1; 
    for(int i=2;i<=sqrt(n);i++) 
    {
        if(n%i==0)
        {
            return false;
        }
    }   
    return true;
}
1

Przeczytałem tą hipotezę i brzmi ona troszkę inaczej

każda liczba naturalna parzysta większa od 2 jest sumą dwóch liczb pierwszych.

Więc tak naprawdę liczby te to są liczby parzyste. I teraz wystarczy znaleźć rozkład ,każdej liczby parzystej z zakresu.

#include <iostream>
#include <math.h>
using namespace std;

bool pierwsza(int n);

int main()
{
    int n;

    cin >> n;

    for (int i = 4; i < n; i += 2)
    {
        if (pierwsza(i - 2)) cout << i << " " << 2 << " " << i - 2 << "\n";
        else if (pierwsza(i - 3)) cout << i << " " << 3 << " " << i - 3 << "\n";
        else
        {
            for (int j = 5; ; j += 6)
            {
                if ((pierwsza(j) && pierwsza(i - j)))
                {
                    cout << i << " " << j << " " << i - j << "\n";
                    break;
                }
                else if (pierwsza(j + 2) && pierwsza(i - j + 2))
                {
                    cout << i << " " << j + 2 << " " << i - j + 2 << "\n";
                    break;
                }
            }
        }


    }

    return 0;
}

bool pierwsza(int n)
{
    if (n <= 3)
        return true;
    if (n % 2 == 0 || n % 3 == 0)
        return false;
    int root = sqrt(n);
    for (int i = 5; i <= root; i += 6)
        if (n % i == 0 || n % (i + 2) == 0)
            return false;

    return true;
}

delikatnie zmodyfikowany kod od @lion137

Już chyba ostatnia edycja :)

1

Znowu Masz buga w pierwsza, ma być:if (n <=3) return n >= 2.

1 użytkowników online, w tym zalogowanych: 0, gości: 1