Potęgowanie C++

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

    using namespace std;


    int main()
    {

    	int ilosc, a, b, c;

    	cout << "Ile liczb chcesz wpisac?: ";
    	cin >> ilosc;

    	for (int i = 0; i < ilosc; i++)
    	{
    		cout << "wpisz podstawe a i b " << endl;
    		cin >> a >> b;
    		c = pow(a, b);
    		if (c < 10)
    			cout << c << endl;
    		else {
    			c = c % 10;
    			cout << c << endl;
    		}
    	}

    	
    }

Dla danych dwóch liczb naturalnych a i b, wyznaczyć ostatnią cyfrę liczby ab.

Zadanie
Napisz program, który:
wczyta ze standardowego wejścia: podstawę a oraz wykładnik b,
wyznaczy ostatnią cyfrę liczby ab,
wypisze wynik na standardowe wyjście.
Wejście
W pierwszej linii wejścia znajduje się jedna liczba całkowia D (1≤D≤10), oznaczjąca liczbę przypadków do rozważenia. Opis każdego przypadku podany jest w jednym wierszu, zawierającym dwie liczby naturalne a i b oddzielone pojedynczym odstępem (spacją), takie, że (1 ≤ a,b ≤ 1 000 000 000).

Wyjście
Dla każdego przypadku z wejścia Twój program powinien wypisać (w osobnej linii dla każdego przypadku z wejścia) cyfrę jedności liczby ab zapisanej dziesiętnie.

Przykład
Dla danych wejściowych:
2
2 3
3 3
poprawną odpowiedzią jest:
8
7

to mój kod, wedle podanego zadania i przykładu działa, ale sędzia nie uznaje, ktoś podpowie?

1

Przede wszystkim, nie działa poprawnie dla przykładu

2
2 3
3 3

Poprawną odpowiedzią jest:

8
7

Twój skrypt odpowiada:

Ile liczb chcesz wpisac?: 

wpisz podstawe a i b 
8
wpisz podstawe a i b 
7

Ale podstawowym problemem tutaj jest to, że odpowiedzi bardzo szybko wyjdą poza zakres dowolnego typu liczbowego (w tym double zwracanego przez pow()), i trzeba zauważyć pewne zależności charakteryzujące wyniki. Np. to, że są okresowe.

0

jak zauwazylem, moj kod bedzie tylko dla liczb 2 cyfrowych poprawny, bo jesli bedzie 3 cyfrowa to zwroci druga liczbe, ale jak temu zaradzic?

1

Nie bardzo wiem jak doszedłeś do takiego wniosku. Ale mam taką sugestię: policz sobie kolejne potęgi np. liczby 4. Albo 14. Najlepiej pisemnie, żebyś zauważył które cyfry wpływają na wartość ostatniej cyfry wyniku. Może zauważysz pewną zależność.

1

ostatnie cyfry potęgi liczby: (>10)
2 to 2,4,6,8
3 to 1,3,7,9
4 to 6,4
5 to 5
6 to 6
7 to 1,3,7,9
8 to 2,4,6,8
9 to 9,1

o to chodzi?

0

Dokładnie tak. Teraz wystarczy to ubrać w kod i masz zadanie rozwiązane (+ wziąć pod uwagę moją uwagę z pierwszego posta)

0

czyli jeszcze zamiast int, dac long double tak?

1

Nie, int jest tutaj poprawnym typem danych. double jest typem zmiennoprzecinkowym, a Ty ułamków nigdzie jego właściwości tu nie potrzebujesz. Wręcz przeciwnie.

Chodziło mi o to, że wypisujesz znacznie więcej tekstu niż wymaga tego zadanie. To jest błąd.

0

czyli pętlę zostawić, a potem ify dla kazdej podstawy od 2 do 9?

0

A co z 0 i 1?

0

0 do jakiejkolwiek potęgi da 0, zaś 1 da zawsze 1

0

No tak. Ale nie możesz zapomnieć ich wziąć pod uwagę. Najlepiej by było gdybyś zrobił sobie osobną funkcję do liczenia ostatniej cyfry n-tej potęgi danej liczby i po prostu w pętli ją odpalał. Ale jeśli tego nie chcesz robić to spróbuj po swojemu i pokaż efekt.

0

teraz tylko jak sprawdzić, który przypadek jest prawidlowy dla danej liczby, przykładowo a=2, b=5, zadziała if (a==2), ale z dwójką przypadków jest cztery (2,4,6,8)

0

Przypadki są zawsze w tej samej kolejności, użyj modulo.

0
#include <iostream>
#include<cmath>

using namespace std;


int liczeniepotegi(int a, int b)
{
    int wynik;
    if (a == 0)
        return 0;
    else if (a == 1)
        return 1;
    else if (a == 2)
    {
        wynik = pow(a, b);
        wynik = wynik % 10;
        return wynik;
    }
    else if (a == 3)
    {
        wynik = pow(a, b);
        wynik = wynik % 10;
        return wynik;
    }
    else if (a == 4)
    {
        wynik = pow(a, b);
        wynik = wynik % 10;
        return wynik;
    }
    else if (a == 5)
    {
        return 5;
    }
    else if (a == 6)
    {
        return 6;
    }
    else if (a == 7)
    {
        wynik = pow(a, b);
        wynik = wynik % 10;
        return wynik;
    }
    else if (a == 8)
    {
        wynik = pow(a, b);
        wynik = wynik % 10;
        return wynik;
    }
    else if (a == 9)
    {
        wynik = pow(a, b);
        wynik = wynik % 10;
        return wynik;
    }

}



int main()
{

    int ilosc, a, b, c;

    cout << "Ile liczb chcesz wpisac?: ";
    cin >> ilosc;

    for (int i = 0; i < ilosc; i++)
    {
        cout << "wpisz podstawe a i b " << endl;
        cin >> a >> b;
        cout << liczeniepotegi(a, b);
        
    }
    

}

coś takiego udalo mi sie napisać, niby dla przypadków dobrze, ale dla pewnosci spytam xd

1

Ookej... Zależność zauważyłeś, ale zupełnie olałeś. Użycie pow() w tym zadaniu to błąd.

Może to Ci pomoże - na przykładzie liczby 2:

wykładnik ostatnia cyfra
1 2
2 4
3 8
4 6
5 2
6 4
7 8
8 6

Widzisz zależność? Użyj jej.

0

tak, wcześniej już zauwazylem ale szczerze mówiąc, nie mam pojecia jak jej użyć

1

Jak już pisałem - użyj modulo/reszty z dzielenia. Masz kolejnego hinta:

wykładnik | wykładnik modulo okres (4) | ostatnia cyfra
---------------- | -------------------
1 | 1 | 2
2 | 2 | 4
3 | 3 | 8
4 | 0 | 6
5 | 1 | 2
6 | 2 | 4
7 | 3 | 8
8 | 0 | 6
9 | 1 | 2
10 | 2 | 4

0
#include <iostream>
#include<cmath>

using namespace std;


int  LiczenieOstCyfryPotegi(int a, int b)
{
    int wynik;
    if (a == 0)
        return 0;
    else if (a == 1)
        return 1;
    else if (a == 2)
    {
        if (b % 2 == 0)
            return 4 albo 6;
        else return 2 albo 8;
    }
    else if (a == 3)
    {
        if (b % 2 == 0)
            return 9 albo 1;
        else return 3 albo 7;
    }
    else if (a == 4)
    {
        if (b % 2 == 0)
            return 6;
        else return 4;

    }
    else if (a == 5)
    {
        return 5;
    }
    else if (a == 6)
    {
        return 6;
    }
    else if (a == 7)
    {
        if (b % 2 == 0)
            return 4 albo 1;
        else return 7 albo 3;
    }
    else if (a == 8)
    {
        if (b % 2 == 0)
            return 4 albo 6;
        else return 8 albo 2;
    }
    else if (a == 9)
    {
        if (b % 2 == 0)
            return 1;
        else return 9;
    }

}



int main()
{

    int ilosc, a, b, c;

    cout << "Ile liczb chcesz wpisac?: ";
    cin >> ilosc;

    for (int i = 0; i < ilosc; i++)
    {
        cout << "wpisz podstawe a i b " << endl;
        cin >> a >> b;
        cout << LiczenieOstCyfryPotegi(a, b);
        
    }
    

}

chyba zczailem koncept, ale nie wiem jeszcze jak poradzic sobie z poczwórnymi warunkami, bo podwójne po prostu rozdzieliłem je na warunki parzyste i nieparzyste

i wiem ( pogladowo dalem sobie to "albo", bo nie wiem jak sobie z tym poradzić)

0

No już blisko, ale nie zauważyłeś, że jak okres jest 4 (tak jak w przykładzie, który ztablicowałem wyżej) to istotna jest wartość modulo okres, a nie modulo 2.

Może kolorki pomogą.

screenshot-20201031150744.png

0
#include <iostream>
#include<cmath>

using namespace std;


int  LiczenieOstCyfryPotegi(int a, int b)
{
    int wynik;
    if (a == 0)
        return 0;
    else if (a == 1)
        return 1;
    else if (a == 2)
    {
        if (b % 4 == 1)
            return 2;
        else if (b % 4 == 2)
            return 4;
        else if (b % 4 == 3)
            return 8;
        else if (b % 4 == 0)
            return 6;
    }
    else if (a == 3)
    {
        if (b % 4 == 1)
            return 3;
        else if (b % 4 == 2)
            return 9;
        else if (b % 4 == 3)
            return 7;
        else if (b % 4 == 0)
            return 1;
    }
    else if (a == 4)
    {
        if (b % 2 == 0)
            return 6;
        else return 4;

    }
    else if (a == 5)
    {
        return 5;
    }
    else if (a == 6)
    {
        return 6;
    }
    else if (a == 7)
    {
        if (b % 4 == 1)
            return 7;
        else if (b % 4 == 2)
            return 9;
        else if (b % 4 == 3)
            return 3;
        else if (b % 4 == 0)
            return 1;
    }
    else if (a == 8)
    {
        if (b % 4 == 1)
            return 2;
        else if (b % 4 == 2)
            return 4;
        else if (b % 4 == 3)
            return 8;
        else if (b % 4 == 0)
            return 6;
    }
    else if (a == 9)
    {
        if (b % 2 == 0)
            return 1;
        else return 9;
    }

}



int main()
{

    int ilosc, a, b, c;

    cout << "Ile liczb chcesz wpisac?: ";
    cin >> ilosc;

    for (int i = 0; i < ilosc; i++)
    {
        cout << "wpisz podstawe a i b " << endl;
        cin >> a >> b;
        cout << LiczenieOstCyfryPotegi(a, b);
        
    }
    

}

chyba dobrze i do tego zrozumialem skad to sie wzielo i jak to napisać

1

Już całkiem nieźle. Teraz jeszcze musisz wziąć pod uwagę potęgę 0 (cokolwiek do 0 to zawsze 1) oraz to, że niepoprawnie wypisujesz - masz wypisywać tylko wyniki, a nie zapytania do użytkownika.

0

Tak naprawdę to można przejmować się zawsze resztą z dzielenia przez 4, a nie przez 2, co może uprościć znacząco kod. Jak już napiszesz coś co działa, to mogę wrzucić zgrabne rozwiązanie.

0
enedil napisał(a):

Tak naprawdę to można przejmować się zawsze resztą z dzielenia przez 4, a nie przez 2, co może uprościć znacząco kod. Jak już napiszesz coś co działa, to mogę wrzucić zgrabne rozwiązanie.

teraz o tym wiem, wtedy jak pisalem latwiej bylo mi zrozumieć poprzez %2

0
kq napisał(a):

Już całkiem nieźle. Teraz jeszcze musisz wziąć pod uwagę potęgę 0 (cokolwiek do 0 to zawsze 1) oraz to, że niepoprawnie wypisujesz - masz wypisywać tylko wyniki, a nie zapytania do użytkownika.

no tak zgadza się, bo wcześniej chodzi o wykładnik (a do 0 = a) , a nie o podstawę (0 do a = 0)

0
#include <iostream>
#include<cmath>

using namespace std;


int  LiczenieOstCyfryPotegi(int a, int b)
{
    int wynik;
    if (b == 0)
        return 1;
    else if (a == 1)
        return 1;
    else if (a == 2)
    {
        if (b % 4 == 1)
            return 2;
        else if (b % 4 == 2)
            return 4;
        else if (b % 4 == 3)
            return 8;
        else if (b % 4 == 0)
            return 6;
    }
    else if (a == 3)
    {
        if (b % 4 == 1)
            return 3;
        else if (b % 4 == 2)
            return 9;
        else if (b % 4 == 3)
            return 7;
        else if (b % 4 == 0)
            return 1;
    }
    else if (a == 4)
    {
        if (b % 2 == 0)
            return 6;
        else return 4;

    }
    else if (a == 5)
    {
        return 5;
    }
    else if (a == 6)
    {
        return 6;
    }
    else if (a == 7)
    {
        if (b % 4 == 1)
            return 7;
        else if (b % 4 == 2)
            return 9;
        else if (b % 4 == 3)
            return 3;
        else if (b % 4 == 0)
            return 1;
    }
    else if (a == 8)
    {
        if (b % 4 == 1)
            return 2;
        else if (b % 4 == 2)
            return 4;
        else if (b % 4 == 3)
            return 8;
        else if (b % 4 == 0)
            return 6;
    }
    else if (a == 9)
    {
        if (b % 2 == 0)
            return 1;
        else return 9;
    }

}



int main()
{

    int ilosc, a, b;
    
    
    cin >> ilosc;
    int* tab = new int[ilosc];

    for (int i = 0; i < ilosc; i++)
    {
        
        cin >> a >> b;
        tab[i]= LiczenieOstCyfryPotegi(a, b);

    }
    for (int i = 0; i < ilosc; i++) {
        cout << tab[i] << endl;
    }

}

ostatecznie zmodyfikowany kod

1

Cały czas nie obsługujesz zerowego wykładnika.

Po co dodałeś dynamiczną alokację i tablicę? Wcześniej było dobrze

1

Ok, to skoro padło już jakieś rozwiązanie, to prezentuję własne, całkiem chyba zwięzłe:

#include <iostream>
#include <cmath>

unsigned PowMod10(unsigned a, unsigned b) {
    if (b == 0)
        return 1;
    // Nie będzie ani przepełnienia ani utraty precyzji double, gdyż wynik
    // nie przekroczy 9^(4+3) < 10^9 < 2^31 < 2^53.
    // Oczywiście, można by to zaimplementować przez zwykłą pętlę, ale w
    // tym zastosowaniu to bez różnicy z punktu widzenia poprawności/wydajności,
    // a przynajmniej jest mniej kodu.
    return ((unsigned)pow(a % 10, 4 + b%4)) % 10;
}

int main() {
    int D;
    std::cin >> D;
    while (D--) {
        unsigned a, b;
        std::cin >> a >> b;
        std::cout << PowMod10(a, b) << "\n";
    }
}
0

dodalem by output jaki jest podany w zadaniu byl taki sam, inaczej zamiast:
Przykład
Dla danych wejściowych:
2
2 3
3 3
poprawną odpowiedzią jest:
8
7

miałbym

2
2 3
8
3 3
7

co do pierwszego >>> if (a == 0)
return 1;
powinno być if (b == 0)
return 1;

0

bądź co bądź wysłany kod na SPOJ, nie działa

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