Zadanko 'liczby pierwsze' ze pl.spoj.com

Zadanko 'liczby pierwsze' ze pl.spoj.com
G1
  • Rejestracja:około 3 lata
  • Ostatnio:13 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:około 5 godzin
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:minuta
  • Postów:4888
0

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


Althorion
Moderator C/C++
  • Rejestracja:prawie 10 lat
  • Ostatnio:dzień
  • Postów:1603
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 3 godziny
  • Lokalizacja:Kraków
  • Postów:639
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:dzień
  • Postów:1082
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:około 5 godzin
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:około 2 godziny
  • Postów:699
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:minuta
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.
Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)