Zadanie PA05_POT ze SPOJ - kod daje błędne wyniki

0

Witam wszystkich. Celem programu jest wyznaczanie ostatniej cyfry z liczb podniesionych do potęgi. - http://pl.spoj.com/problems/PA05_POT/
Mam problem z kodem - wydaje mi się poprawny, jednak daje błędne wyniki. Przykładem mogą być tutaj 1^7; 0^5 czy 2^3.
Kod analizowałem ale za cholerę nie mogę znaleŹć przyczyny problemu.

#include <stdio.h>
//bledna odpowiedz ? ;(

int obcinamy (unsigned long long int x) {
    return(x % 10);
}

int cyfry (unsigned long long int A, unsigned long long int B) {
    //tylko ostatnia cyfra
int AA = obcinamy(A);

if (B==0) return 1;
else if (AA==0 || AA==1) return A;
else if (AA == 2) {
    B = B % 4;
    if (B == 0) return 6;
    else if (B == 1) return 2;
    else if (B == 2) return 4;
    else if (B == 3) return 8;
}
else if (AA == 3) {
    B = B % 4;
    if (B == 0) return 1;
    else if (B == 1) return 3;
    else if (B == 2) return 9;
    else if (B == 3) return 7;
}

else if (AA == 4) {
    B = B % 2;
    if (B == 0) return 6;
    else if (B == 1) return 4;
}

else if (AA == 5) return 5;

else if (AA == 6) return 6;

else if (AA == 7) {
    B = B % 4;
    if (B == 0) return 1;
    else if (B == 1) return 7;
    else if (B == 2) return 9;
    else if (B == 3) return 3;
}

else if (AA == 8) {
    B = B % 4;
    if (B == 0) return 6;
    else if (B == 1) return 8;
    else if (B == 2) return 4;
    else if (B == 3) return 2;
}

else if (AA == 9) {
    B = B % 2;
    if (B == 0) return 1;
    else if (B == 1) return 9;
}
}



int main() {
unsigned long long int a, b;
int n, licznik;
scanf("%d", &n);

for (licznik = 0; licznik < n; ++licznik) {
    scanf("%d", &a);
    scanf("%d", &b);
    printf("%d\n", cyfry(a,b));
}


return 0;
}

3

A czytał Pan co kompilator mówi?

prog.cc: In function 'int main()':
prog.cc:68:19: warning: format '%d' expects argument of type 'int*', but argument 2 has type 'long long unsigned int*' [-Wformat=]
     scanf("%d", &a);
                 ~~^
prog.cc:69:19: warning: format '%d' expects argument of type 'int*', but argument 2 has type 'long long unsigned int*' [-Wformat=]
     scanf("%d", &b);
                 ~~^

Górna część 64-bitowych zmiennych wciąż jest niezainicjalizowana i jej odczyt (a zatem i całej liczby) to UB. W sumie już zapis do liczby jako innego typu to zapewne UB.

Zmień typ danych na zgodny z formatem scanf (lub zmień format, ale tutaj 32-bitowy int zdecydowanie wystarczy) i zacznie działać.

0

W moim przypadku (korzystam z Code::Blocks pod windowsem) kompilator nie pokazał żadnych ostrzeżeń czy błędów. Dopiero zaczynam przygodę z programowaniem ;)

Zmiana typu danych oczywiście pomogła. Bardzo dziękuję.

0

Być może musisz dodać -Wall i -Wextra do opcji wywołania kompilatora.

1

zamiast takiej tony elifow, mozna po prostu wykorzystac fakt ze ostatnia cyfra sie powtarza okresowo

2^n
2
4
8
16
32
64
128
256

tablica z ostatnich cyfr 4 pierwszych poteg: [2, 4, 8, 6]

np 2^97
97 mod 4 = 1

czyli nasza cyfra jest pierwszym (z indeksem 0) elementem w tablicy
tablica[0] == 2

dla pewnoscI:
2 ** 97
158456325028528675187087900672

PS. reszta 0 to w tym przypadku ostatni element

1

Było już wielokrotnie na forum: https://4programmers.net/Forum/C_i_C++/289696-spoj_potegowanie?p=1361874#id1361874

A problem stanowi zły parametr formatu dla scanf oraz printf tak jak napisał @kq.

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