1 / 13
Oct 2022

Twój kod zwraca odpowiedź tylko dla jednego testu.

Pewna liczba zestawów danych (nie więcej niż milion).

Dzięki, znów kopiuj wklej mnie kopnęło, zafiksowałem się na algorytmie i prosty błąd mnie zgubił. Jeszcze raz dzięki.

10 months later

Witam,
mógłby ktoś sprawdzić poprawność tych testów:
in:
6
14 35
20 30
99999 999999
5432 8954672
100 100
1 999999999
out:
171.50
125.00
12100077.00
14779724538.07
400.00
1000000000000000000.00
i podać jakieś inne przykłady.

Jedno co widzę nie tak to ta 6 na początku
w zadaniu nie ma określonej liczby testów
powinieneś to ogarnąć bez podania liczby testów na początku.

BTW wyniki mam te stame jak usunę tę 6 z początku

Ciekawe czy ktoś rozwiązał to zadanie innym językiem niż C?
Ja próbowałem w sposób zoptymalizowany w Swift i mam przekroczenie czasu:

import Foundation

var (p, q, x, y) = (Int(), Int(), Double(), Double())

while let c = Optional(getchar_unlocked()), c != EOF {
    p = (p<<1) + (p<<3) + Int(c) - 48
    
    while let c = Optional(getchar_unlocked()), c != 32 {
        p = (p<<1) + (p<<3) + Int(c) - 48
    }
    
    while let c = Optional(getchar_unlocked()), c != 10 {
        q = (q<<1) + (q<<3) + Int(c) - 48
    }
    
    (x, y) = (Double(p), Double(q))
    print(String(format: "%.2f", round((1 + y/x) * (x + y) * 100) / 100))
    
    (p, q, x, y) = (0, 0, 0, 0)
}

Swift namiętnie sprawdza zgodność typów - czy to może być główny powód jego opóźnień?
A może robię coś źle?

Jak by był zaktualizowany kompilator Swifta to powinno przejść takie coś:

while let p = readLine()?.split(separator: " ").compactMap({ Double($0)! }) ?? nil {
    print(String(format: "%.2f", round((1 + p[1]/p[0]) * (p[0] + p[1]) * 100) / 100))
}

W C napisałem tak:

#include <stdio.h>
#include <math.h>

int main() {
    long p = 0, q = 0;
    
    while (scanf("%ld %ld", &p, &q) != EOF) {
        
        printf("%.2lf\n", round((1 + (double)q/p) * (p + q) * 100) / 100);
        p = (q = 0);
    }
    
    return 0;
}

Ale optymalniej okazało się tak:

#include <stdio.h>
#include <math.h>

int main() {
    long p, q, c;
    
    while ((c = getchar_unlocked()) != EOF) {
        p = c - '0';
        
        while ((c = getchar_unlocked()) != ' ') {
            p = (p<<1) + (p<<3) + c - '0';
        }
        
        q = 0;
        while ((c = getchar_unlocked()) != '\n') {
            q = (q<<1) + (q<<3) + c - '0';
        }
        
        printf("%.2f\n", round((1 + (double)q/p) * (p + q) * 100) / 100);
    }
    
    return 0;
}

Prośba do mądrzejszych ode mnie - Co w tych kodach można byłoby dopracować?

Dobrze napisany kod, będzie dobry w każdej wersji kompilatora. W nowej na pewno łatwiej pisać kod, ale jeżeli będzie źle napisany to kompilator, nawet najnowszy nie pomoże, ani nie zagwarantuje szybszego kodu.
Jeżeli jednak tak bardzo zależy Ci na nowszej wersji, to czy napisałeś już, jak Ci radzono do adminów? Oni tu nie mają czasu ani potrzeby zaglądać, a nikt z nas nie ma takich uprawnień.

Jadę pkp i pisałem na komórce i skasował mi się cały list.
W każdym razie, najpierw zalicz zadanie bez optymalizacji i udziwnień, a dopiero potem baw się w ulepszanie.

Tak to zadanie rozwiązano np w pytonie, tu praktycznie nie ma ograniczeń czasowych, przeczytaj bardzo, bardzo dokładnie treść zadania.

Napisałem prośbę o aktualizację kompilatora Swifta do wersji 5.8.1. Nie ma żadnej odpowiedzi. Próbowałem kilka zadań rozwiązać w języku Fortran 90/2018 ale się nie dało. Przeglądając forum wersji angielskiej natknąłem się na kogoś kto też narzekał że kompilator Fortrana że jest stary. Szkoda bo w numerycy jest szybszy od C. - Może by tak parę osób napisało do adminów aby zaktualizowali kompilatory.
Zadanie MWP4_3C - Płyta główna napisałem w Fortranie ale nie przeszło chociaż mocno je przetestowałem:

program TEST
    implicit none
    character(len=1) :: c
    integer :: i, k, d, n, s, p

    read(*, *) k
    do i = 1, k, 1
        s = 0
        p = 65
        do
            read(*, '(a1)', advance='no', eor=100) c
            n = ichar(c)
            if(n == 10) exit
            d = abs(p - n)

            if (d <= 13) then
                s = s + d
            else
                s = s + 26 - d
            end if

            p = n
        end do

100 continue
        write(*, '(i0)') s
    end do
    stop
end

Jeżeli chodzi o szybkość kodu w C, to już to zrobiłeś sam. Ja Ci nie pomogę w tym.
Jeżeli chodzi o jakość kodu, która nie wpłynie na szybkość, to mogę napisać co mi się nie podoba:

  1. Twoja metioda wczytywania dobrze działa dla danych typu:
      <dane><space><dane><enter>
      <dane><space><dane><enter>
      ..............
      <dane><space><dane><enter>
      <EOF>

Potestuj dla takich:

      <dane><space><space><tabulator><dane><tab><tab><enter>
      <dane><space><dane>
      <EOF>

lub:

      <dane><space><dane><enter>
      <dane><space><dane><enter>
      ..............
      <dane><space><dane> <EOF> /// brak enteru przed EOF 

lub

      <dane><space><dane><enter>
      <dane><space><dane><enter>
      ..............
      <dane><space><dane><enter>
      <pusta linia/linie - spacje, tabulator/y itd
      <EOF>

Dane testowe powinny być czyste, ale inne języki [przy normalnym wczytywaniu] radzą sobie same z takimi danymi bez konieczności specjalnego traktowania. Jeżeli sami piszemy szybki kod wczytywania, to powinniśmy to uwzględnić i potestować.

  1. Jeżeli wczytujemy dane do zmiennych, nie ma potrzeby ich wcześniej zerować. Operacja wczytywania zamazuje poprzednią zawartość zmiennej - piszę o “normalnym” wczytywaniu
  2. To jest bez sensu:
    printf("%.2f\n", round((1 + (double)q/p) * (p + q) * 100) / 100);
    
    wystarczy:
    printf("%.2f\n", (1 + (double)q/p) * (p + q) );
    

Jeżeli chcesz się pozbyć dzielenia na typie zmiennopozycyjnm, zamieniając je na dzielenie całkowito liczbowe, robisz kosztem dodatkowego dzielenia i mnożenia przez 100 a to już nie koniecznie jest opłacalne. Jeżeli jednak chcesz koniecznie to widzę to tak;

int x, y;
zamiast: 
wynik = (double) x / y;  --> printf ("%.2f\n", wynik);

 można np tak:
 wynik1_pośredni_część całkowita = x / y // dzielenie całkowite
wynik2_pośredni_2_miejsca_po przecinku = (100 * x / y) % 100 // nawiasy nie są konieczne. Grozi przepełnienie
a potem
printf ("%ld,02ld\n", wynik1, wynik2); //wynik2 z zerami wiodącymi.

Pisałem o języku C, ale to dotyczy także twoich kodów w innych językach.

O Fortranie parę moich refleksji-przemyśleń, przy następnej okazji - jeżeli będziesz mocno zainteresowany

Gorące dzięki za merytoryczne rady właśnie o to mi chodziło.