1 / 32
Nov 2016

Witajcie.
Kod przetestowany na wszystkie sposoby, a niestety odrzucone przez SPOJ - Błędna odpowiedź
Nawet czas wypisania wszystkich 30 przypadków to 0.3sek. Wszystkie wyniki są poprawne tak myślę tzn
0 1
0 2
0 6
2 4
2 0
2 0
4 0
2 0
8 0
0 0
...
0.0

A kod wygląda tak:

#include <iostream>

using namespace std;
int ilosc_testow, liczba, il_10, il_1, silnia=1;

int main()
{
    cin >> ilosc_testow;
    for (int i=0; i<ilosc_testow; i++) {
        cin >> liczba;
        if ((liczba > 0) && (liczba <=30)) {
        if (liczba > 9) cout << 0 << " " << 0 << endl;
        else {
        for (int j=1; j<=liczba; j++) {
            silnia=j*silnia;
        }
        il_10 = (silnia%100)/10;
        il_1 = silnia%10;
        cout << il_10 << " " << il_1 << endl;
        }
        silnia=1;
        }
    }
    return 0;
}
  • created

    Nov '16
  • last reply

    Oct '21
  • 31

    replies

  • 2.2k

    views

  • 13

    users

  • 7

    likes

  • 2

    links

OK Mój błąd, ale po poprawkach program działa dla wiekszych liczb ale ciągle w odpowiedzi mam błędna odpowiedź

#include <iostream>
#include <math.h>

using namespace std;
double liczba,  silnia=1;
int ilosc_testow,il_10, il_1;

int main()
{
    cin >> ilosc_testow;
    for (int i=0; i<ilosc_testow; i++) {
        cin >> liczba;
        if (liczba > 0) {
        if (liczba > 9) cout << 0 << " " << 0 << endl;
        else {
        for (int j=1; j<=liczba; j++) {
            silnia=j*silnia;
        }
        il_10 = (fmod(silnia,100))/10;
        il_1 = fmod(silnia,10);
        cout << il_10 << " " << il_1 << endl;
        }
        silnia=1;
        }
    }
    return 0;
}

to może przeczytaj raz jeszcze, tym razem uważnie, treść zadania,

3 months later

Witam, podepnę się pod wątek bo mam podobny problem. Kod wielokrotnie poprawiałem. Mieszczę się w czasie wykonania uwzględniam n=<1, podaje w wyjściu tylko ilość jedności i dziesiątek, ale nadal Pan Sędzie mówi NIE:)

a co ma powiedzieć sędzia, gdy program kończy się błędem - każesz programowi wykonać coś, czego nie może zrobić - więc sędzia nie sprawdza już poprawnego :slight_smile: wyniku

czyli podobny efekt, jak gdybyś na egzaminie poprawnie wypełnił kartę odpowiedzi, ale potem wyrzucił ją przez okno zamiast oddać komisji

mariusz193 dziękuję za podpowiedź :slight_smile: Od kilkunastu dni uczę się C++ i nigdy wcześniej nie miałem nic wspólnego z programowaniem. Przerobiłem kilkanaście odcinków tutoriala i w jednym z nich, gdzie były omawiane wskaźniki widziałem, że trzeba zniszczyć tablicę na końcu, by nie zajmować pamięci i na małpę to powtarzam :slight_smile: Po usunięciu delete [] tab Pan Sędzia powiedział Niech Ci będzie :wink: . Raz jeszcze dzięki za podpowiedź.

Pamięć powinna być zwolniona, ale próbowałeś zwolnic coś innego niż zarezerwowałeś

A generalnie, to tablica nie jest potrzebna, bo można od razu w pętli wypisywać wynik

Usuń link do kodu, niech inni nie mają za łatwo

Kod usunięty. Następne zadanie z potęgowania wykonałem wykorzystując pętlę while. Niestety nadal nie wiem dlaczego zniszczenie tablicy na końcu kodu było błędem. Dzięki za podpowiedzi..

Zniszczenie tablicy było błędem, bo wskaźnik nie pokazywał już na początek tablicy - kazałeś mu się przesuwać na kolejne elementy tablicy. Gdyby wskazywał cały czas na początek tablicy, to sędzia by nie protestował przy zwalnianiu obszaru pamięci tej tablicy.

Nie wiedziałem że jest taka zasada, ale teraz już rozumiem. Nie wiem jeszcze tylko dlaczego zniszczenie tablicy nie było błędem w Code Bloks'ie w którym pisze kod??

Zasadniczo nie można tu mówić o 'zniszczeniu tablicy', bo wskaźnik w ostatnim kroku wychodził poza tablicę. Niszczyłeś więc coś co znajdowało się zaraz za tablicą i dlatego SPOJ reagował errorem SIGABRT. Dlaczego w CodeBlocksie nie było błędu? To już trzeba się zagłębić w teorię jak operatory new[] i delete[] realizują funkcję alokowania i zwalniania pamięci. Moja hipoteza jest taka, że operator new[] nie zawsze alokuje dokładnie takiej ilości pamięci jaka jest żądana, ale czasami zaokrągla tą ilość w górę - tak by ilość była wielokrotnością konkretnej stałej ilości pamięci. Być może testując na C::B miałeś do czynienia z tą powiększoną tablicą. Potestuj u siebie z takimi testami, by tablica osiągała coraz większe rozmiary, a być może trafisz na test gdzie też się wysypie z errorem SIGABRT.

Hey, jestem właśnie w trakcie rozwiązywania tego zadania i po prostu się poddaję. Próbowałem iteracją, próbowałem rekurencją i nadal sędzia mówi, że przekroczyłem limit czasu. Możecie coś doradzić? Oto kody:

Rekurencja (zdania w cudzysłowie wywaliłem rzecz jasna):

Summary

include

include

using namespace std;

long long int silnia_f (long long int n)
{
if (n <= 1) return 1;
else return n*silnia_f(n-1);
}

int main()
{

long long int n,silnia, dziesiatki, jednosci;

cout<<"Podaj ilosc liczb do sprawdzenia: ";
cin>>n;

if(n<0)
{
cerr<<"Podales liczbe ujemna!";
exit(0);
}
else if(n>30)
{
cerr<<"Podales za duzo ilosc liczb do sprawdzenia!";
exit (0);
}

int tab[n];

for(int i=0; i<n; i++)
{
cout<<"Podaj liczbe: ";
cin>>tab[i];
}

for(int i=0; i<n; i++)
{

 silnia=silnia_f(tab[i]);

 dziesiatki=(silnia/10)%10;
 jednosci=silnia%10;

  cout<<dziesiatki<<" ";
  cout<<jednosci<<endl;

}

delete [] tab;

return 0;

}

Iteracja:

Summary

include

using namespace std;

int main()
{
long long int, n,silnia, m, dziesiatki, jednosci;

cout<<"Podaj ilosc liczb do sprawdzenia: ";
cin>>n; // ile liczb

int tab[n];

for(int i=0; i<n; i++)
{
cout<<"Podaj liczbe: ";
cin>>tab[i];
}

for(int i=0; i<n; i++)
{
silnia=tab[i];
m=tab[i];

 for(int j=1; j<m; j++)
 {
     tab[i]--;
     silnia=silnia*tab[i];
 }

 dziesiatki=(silnia/10)%10;
 jednosci=silnia%10;

  cout<<dziesiatki<<" ";
  cout<<jednosci<<endl;

}

return 0;

}

wersja rekurencyjna jest blizsza rozwizania. Nie potrzebnie próbujesz liczyć całą silnię skoro potrzebujesz tylko 2 ostatnie cyfry. Jeśli jeszcze usuniesz te dodatki z outputu poprawisz powinno być AC.

PS Nie potrzebnie tablicujesz wyniki. Możesz po prostu pobrać 1 liczbę, policzyć, wypisać wynik i pobrać kolejną

PS 2 dane na wejściu są zawsze zgodne z specyfikacją podaną w zadaniu

PS 3 kod najlepiej linkuj do ideone.com wtedy nie jest pocięty i można go łątwo przetestować.

Teraz kod wygląda tak: http://ideone.com/Cpk17131

Nadal mam błąd. O co tutaj chodzi? Jak inaczej mam wyznaczyć te dwie ostatnie cyfry bez wykonywania kalkulacji i policzenia silni? Czego ten program oczekuje, żeby limit czasu się zgadzał? Nie mam pojęcia co mam jeszcze wywalić.

Znowu ukróciłem, tym razem do granic możliwości, też nie akceptuje: http://ideone.com/riZCej41

druga wersja jest lepsza ale dalej niepotrzebnie liczysz całą silnię. Weź kalkulator i policz sobie silnie z liczb od 1 do 15. wtedy będziesz wiedzieć jak zrobić to zadanie

Czy chodzi Ci o to, że dla każdej liczby powyżej 9 jedności i dziesiątki silni to zawsze 0 i 0? No bo nie rozumiem jak można wyznaczyć dziesiątki i jedności jakiejś liczby bez liczenia jej. Czy o to chodzi, czy co coś innego?