Skocz do zawartości

[C++]Samowolna zmiana wartości zmiennej


Force

Polecane posty

Otóż, mam zadanie, napisać program w c++, który dostaje tam ileś zestawów danych, i każdy zestaw to ilość kul białych i czarnych i za zadania jest powiedzieć, czy gracz pierwszy ma strategi wygrywającą, a jeśli nie to chociaż remisującą. Mam tam kilka możliwych ruchów, ale nie w tym rzecz. Otóż pod czas działania programu wartości zmiennych same się zmieniają co powoduje, że program złe wyniki wyświetla. Modyfikowane są zmienne Count, White i Black co się robi frustrującą. Zauważyłem, że wartości zmiennych się modyfikują gdy dojdzie do pętli w linii 34 i gdy robi się nowa iteracja to się modyfikują. Nie będę tłumaczył co kod ma robić bo dużo by tłumaczyć, chodzi o to gdzie dochodzi do zmiany wartości i w ogóle czemu do niej dochodzi.

 
#include <cstdio>

int Count; // Liczba zestawów
int Black; // Liczba czarnych
int White; // Liczba białych
// Pierwsza współrzędna to białe, druga czarne
int tab [8][5001];


int main()
{
       scanf("%d",&Count);
       //printf("%d\n",Count);
       for(int i=0;i<Count;++i){
               // Pobieram ilość kulek
               scanf("%d %d",&White,&Black);
               //printf("%d %d\n",White,Black);
               //printf("%d\n",Count);
               // Inicjuję tablicę
               for(int j=0;j<=Black;++j)
                       tab[0][j] = tab[1][j] = tab[2][j] = tab[3][j] = 0;
               tab[0][0] = 2;
               tab[1][0]=tab[1][2]=1;
               tab[2][0]=tab[2][2]=2;
               tab[3][0]=tab[3][2]=tab[3][4]=1;
               // jeśli ilość białych jest większa niż 5 to włącz przerabianie
               if (White>3){
                       // Jeśli jest to kolumna czarnych od 0 do 2 to już mogę wiedzieć czy da się
                       // da to także możliwość nie sprawdzania warunków czy odejmując 2 lub 3 nie wyjdę poza zakres
                       if (Black <=2){
                               if (Black == 1)
                                       tab[White%8][1] = 0;
                               else
                                       tab[White%8][0] = tab[White%8][2] = (White-1)%2+1;
                       }
                       else{ // W tej pętli robi mi się błąd
                               for(int j = 4;j<=White;++j){
                                       int min = (j+10 < Black) ? j+10 : Black;
                                       tab[j][0] = tab[j][2] = (j-1)%2+1;
                                       tab[j][1] = 0;

                                       for(int k = 3;k<=min;++k){
                                               bool mat;
                                               bool pat;
                                               mat = (tab[(j-1)%8][k] == 2) || (tab[(j-1)%8][k-2] == 2) || (tab[(j-3)%8][k-2] == 2) || (tab[(j-4)%8][k-3] == 2);
                                               pat = (tab[(j-1)%8][k] == 0) || (tab[(j-1)%8][k-2] == 0) || (tab[(j-3)%8][k-2] == 0) || (tab[(j-4)%8][k-3] == 0);
                                               if (mat)
                                                       tab[j%8][k]= 1;
                                               else
                                                       if (pat)
                                                               tab[j%8][k]= 0;
                                                       else
                                                               tab[j%8][k]= 2;
                                       }
                               }
                       }
               }
               if (tab[White%8][Black] == 1)
                       printf("1\n");
               else
               if (tab[White%8][Black] == 0)
                       printf("0\n");
               else
                       printf("-1\n");
       }
       return 0;
}

Spróbujecie wpisać takie dane:

9

0 10

400 281

400 282

400 283

399 284

399 285

5000 3562

5000 3563

5000 5000

, powinno się dostać

0

0

-1

1

1

-1

-1

1

0

Baza tysięcy lotnisk: http://airportsbase.com

Link do komentarza
Udostępnij na innych stronach

Jeszcze nie przegladalem programu ale samozmieniajace sie zmienne to na 99,9999% nadpisywanie pamieci. Akurat c++ jest stowrzony do tego typu baboli. Techniki przeciwdzialania:

1) Przeciazyc operatory [ ] tak aby dodac range checking

2) napisac klase do operacji na pamieci/tablicach ktora nie pozwoli na nadpisywanie

3) wstawiac warunki sprawdzajace poprawnosci indeksu przed zapisem do tablicy/pamieci

 

sproboj ktores z powyzszych metod prawie na pewno pomoze

Always Dark<br />u1_tt_logo.png banner-1.pngexFabula-banner.pngson_banner_ubersmall.jpg

Link do komentarza
Udostępnij na innych stronach

Można by tak zrobić, gdyby nie to, że chodzi o szybkość działania, a jak mam przy każdym nawiasie dawać warunek to przekroczę czas. Po za tym musisz spojrzeć na kod, aby zobaczyć, że jest on bardzo prymitywny jeśli chodzi o zmienne - jedna tablica intów, i kilka intów i tyle, zero referencji. Może to wina printf czy scanf? bo ja ich nigdy nie używałem a teraz muszę bo są szybsze. Bo jedyny miejsce gdzie przekazuje wskaźnik/referencję to scanf. Wydaje mi się że to coś z dzieleniem modulo. Bo wydaje mi się, że jak jest pętla to modulo 8 działa także na White i Black, nie wiem jak ale gdy j dojdzie do 8 to wychodzi z pętli a White było np. 238, a robi się na 0

Baza tysięcy lotnisk: http://airportsbase.com

Link do komentarza
Udostępnij na innych stronach

wrzucilem do turbo C++

tak jak mowie przekraczsz tablice

masz zdefiniowane int tab [8][5001];

a lini nr 60 czyli

 

tab[j][0] = tab[j][2] = (j-1)%2+1;

 

j = 9

 

wpisywalem twoje dane ktore podales

 

na poczatek wstaw warunki ograniczajace, przetestuj alg. i jak wszystko bedzie dobrze chodzic usun warunki

 

albo wsadz asserty

Always Dark<br />u1_tt_logo.png banner-1.pngexFabula-banner.pngson_banner_ubersmall.jpg

Link do komentarza
Udostępnij na innych stronach

O kurcze, masz rację, powinno być modulo 8. Nie sądziłem, że przekraczam tablicę bo wolę programować w Delphi i tam by mi od razu poleciało Access Violation-em i bym wiedział, że coś jest źle. Kolejna rzecz na wadę c++, przecież takich jaj nie można sobie robić. Kot wymyślił taką specyfikację języka, że jak wyjdę poza jedną zmienną to włóżmy mnie do innej :D

 

Mój avatar nabiera głębszego znaczenia :D

Baza tysięcy lotnisk: http://airportsbase.com

Link do komentarza
Udostępnij na innych stronach

To programista ma wiedzieć jak działa program i gdzie ew. wyjedziesz poza tablice. Jeśli wyjeżdżasz za zakres to znaczy, że nie przeanalizowałeś algorytmu, który wykonuje się w programie. Jeśli miałoby zawsze sprawdzać, to jak sam zauważyłeś, program strasznie by zwolnił. Poza tym, takie niesprawdzanie czasami się przydaje.

 

Ps.

Mea culpa mea maxima culpa - przyznaję się do offtopu, ale sam się o to Force prosiłeś... ;)

Pozdrawiam,

vo7 (;

Link do komentarza
Udostępnij na innych stronach

Zarchiwizowany

Ten temat jest archiwizowany i nie można dodawać nowych odpowiedzi.

×
×
  • Utwórz nowe...