Force Napisano Październik 7, 2007 Zgłoś Share Napisano Październik 7, 2007 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 More sharing options...
Toster Napisano Październik 7, 2007 Zgłoś Share Napisano Październik 7, 2007 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 /> Link do komentarza Udostępnij na innych stronach More sharing options...
Force Napisano Październik 7, 2007 Autor Zgłoś Share Napisano Październik 7, 2007 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 More sharing options...
Toster Napisano Październik 7, 2007 Zgłoś Share Napisano Październik 7, 2007 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 /> Link do komentarza Udostępnij na innych stronach More sharing options...
Force Napisano Październik 7, 2007 Autor Zgłoś Share Napisano Październik 7, 2007 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 Mój avatar nabiera głębszego znaczenia Baza tysięcy lotnisk: http://airportsbase.com Link do komentarza Udostępnij na innych stronach More sharing options...
Toster Napisano Październik 7, 2007 Zgłoś Share Napisano Październik 7, 2007 he he w TurboC++ dostalem wlasnie AV, pozatym w delphi jest tak samo jak masz $R- Dlatego z tablicami i wskaznikami w C++ trza ostroznie Always Dark<br /> Link do komentarza Udostępnij na innych stronach More sharing options...
Force Napisano Październik 7, 2007 Autor Zgłoś Share Napisano Październik 7, 2007 Ale domyślnie jest chyba $R+, no nie ważne, w ogóle powinno się zawsze sprawdzać zakres, nie powinno być takiej opcji, że można wyłączyć, chyba, że jako rada na forum dla samobójców, aby się pocięli przy pisaniu programu. Baza tysięcy lotnisk: http://airportsbase.com Link do komentarza Udostępnij na innych stronach More sharing options...
Wosiedem Napisano Październik 7, 2007 Zgłoś Share Napisano Październik 7, 2007 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 More sharing options...
Force Napisano Październik 8, 2007 Autor Zgłoś Share Napisano Październik 8, 2007 Ok, w jednym miejscu zapomniałem o modulo, programista powinien wiedzieć co robi, ale jak raz naj kiś czas się rąbnie to języ mógłbym chociaż powiedzieć, że to zrobił, a nie szedł w zaparte Baza tysięcy lotnisk: http://airportsbase.com Link do komentarza Udostępnij na innych stronach More sharing options...
Polecane posty
Zarchiwizowany
Ten temat jest archiwizowany i nie można dodawać nowych odpowiedzi.