Zadanko 'liczby pierwsze' ze pl.spoj.com

Zadanko 'liczby pierwsze' ze pl.spoj.com
G1
  • Rejestracja:około 3 lata
  • Ostatnio:3 dni
  • Postów:52
0

Od dawna mam zrobione to zadanko ale o czasie aż 0.01 .
czy postarać się włożyć ciało funkcji do maih?

SI
  • Rejestracja:prawie 14 lat
  • Ostatnio:18 minut
2

O ile dobrze pamiętam, w tym zadaniu da się stworzyć tablicę bool i "wpakować" do niej co jest liczbą pierwszą a co nie. Żadnych funkcji nie trzeba

lion137
  • Rejestracja:około 8 lat
  • Ostatnio:2 minuty
  • Postów:4923
0

Tak, chociaz, ciekawe czy Miller-Rabin by dal rade.


Althorion
Moderator C/C++
  • Rejestracja:prawie 10 lat
  • Ostatnio:20 minut
  • Postów:1605
2

Co do zasady, wspóczesne kompilatory są na tyle sprytne, że się zorientują, czy inline’owanie funkcji w prostych programach ma sens, czy nie, bez ręcznej interwencji.

Spróbować można, ale początkujący mają potężną tendencję do przeceniania wpływu takich mikrooptymalizacji…

Manna5
  • Rejestracja:prawie 6 lat
  • Ostatnio:około 6 godzin
  • Lokalizacja:Kraków
  • Postów:641
0

Możesz też zamiast przenosić kod z funkcji do funkcji wywołującej po prostu nadać tej funkcji kwalifikator inline co powinno spowodować to samo (chociaż zdarza się że niektóre kompilatory ignorują ten kwalifikator) mimo że logicznie w kodzie źródłowym funkcja pozostanie odrębną funkcją.


MY
  • Rejestracja:ponad 9 lat
  • Ostatnio:7 dni
  • Postów:1083
1

Ja jeszcze dodam do wypowiedzi @Althorion że takie mikrooptymalizacje (w ogólności) mają tyle samo sensu co dyskusja czy i++ vs ++i. Oczywiście przy 1 000 000 000 000 wywołań 1 linijkowej funkcji może mieć znaczenie do ogólnej wydajności.

W tym przypadku pewnie problem jest gdzieś indziej. Spoj jak to spoj, tutaj czasami nawet do zaliczenia zadania wymagane będzie odprawianie magii na IO celem zmieszczenia się w limitach. Swoją drogą 0.01 to nie jest zły wynik. Algorytm zapewne masz optymalny. Musisz szukać w Fast I/O. Jest tam parę tematów na forum.

obscurity
już dawno i++ i ++i optymalizuje się do tego samego
MY
@obscurity oczywiście, ale jeszcze do teraz widuję dyskusje i pouczenia nowicjuszy nad wyższością jednej z tych dwóch wersji. Smutne, że ludzie skupiają się na tych błahostkach. Owszem warto wiedzieć co różni jedna wersja od drugiej, ale żebym tylko realnej pracy miał takie rzeczy do poprawy byłbym bardzo zadowolony :D
Satanistyczny Awatar
Mam dobrą i złą wiadomość. Dobra - są takie formy zatrudnienia. Zła - jest z nimi związana kupa rzeczy która obniża satysfakcję.
SI
  • Rejestracja:prawie 14 lat
  • Ostatnio:18 minut
1

Przy tak niskim czasie, pomóc by pewnie mogło nawet i przechowanie wyników w stringu (nowa linia jako "rozdzielacz), i wypisanie ich naraz po zakończeniu wszystkich obliczeń

Satanistyczny Awatar
  • Rejestracja:ponad 6 lat
  • Ostatnio:8 dni
  • Postów:704
0
sig napisał(a):

O ile dobrze pamiętam, w tym zadaniu da się stworzyć tablicę bool i "wpakować" do niej co jest liczbą pierwszą a co nie. Żadnych funkcji nie trzeba

Niedawno się zastanawiałem patrząc na zadania na spoj jakie tam jest podejście do używania lookup table. Czy temat prowokował jakieś debaty.

MarekR22
Moderator C/C++
  • Rejestracja:około 17 lat
  • Ostatnio:2 minuty
1
Kopiuj
#include <iostream>
#include <array>
#include <exception>

template<size_t N>
class EratostenesSive
{
public:
    constexpr EratostenesSive()
    {
        oddPrimes[0] = false;
        for(size_t i = 1; i < (N + 1) / 2; ++i) oddPrimes[i] = true;
        
        for (size_t p = 3; p * p <= N; p += 2) {
            if (oddPrimes[p/2]) {
                for (size_t i = p * p; i <= N; i += 2 * p) {
                    oddPrimes[i/2] = false;
                }
            }
        }
    }
    
    constexpr bool isPrime(size_t x) const
    {
        if (x < 2) return false;
        if (x == 2) return true;
        if (x > max()) throw std::invalid_argument("Sive limit reached");
        return x%2 != 0 && oddPrimes[x/2];
    }
    
    constexpr size_t max() const {
        return N | 1;
    }
    
private:
    bool oddPrimes[(N + 1) / 2] = {};
};

constexpr auto primes = EratostenesSive<100000>{};

int main()
{
	static constexpr const char* const boolDesc[] {
	    "NIE\n",
	    "TAK\n",
	};
    size_t x, n;
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    std::cin >> n;
    while (n-- && std::cin >> x) {
        std::cout << boolDesc[primes.isPrime(x)];
    }
    return 0;
}

Takie coś, operate o constexpr kompiluje się jako C++14 clang 8.0 i gcc 8.3.
Ergo ładna look up table obliczana w trakcie kompilacji.
Niestarty uzyskuje zwykle czas 0.02 a jedno uruchomianie dało 0.01.
Żeby uzyskać 0.00 stawiam na jakiś jakieś optymalizacje operacji IO, względnie szczęście podczas pomiaru czasu (na SPOJ jest spoko LeetCode pot tym względem to tragedia).

https://godbolt.org/z/WzWsTxacq


Jeśli chcesz pomocy, NIE pisz na priva, ale zadaj dobre pytanie na forum.
Satanistyczny Awatar
Dzięki za przypomnienie dlaczego C++ powinien zostać zdelegalizowany.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.