I SPOJ ma całkowicie rację, że się czepia. DIY 1. Przeczytaj dokładnie treść zadania i postaraj się zrozumieć o co w nim dokładnie chodzi. 2. Testuj swoje kody, np na ideone.com: http://ideone.com/A0wBGo311 3. Szukaj tu na forum i na forum-old wątku na temat zadania, z którym masz problemy.
Powiedziałbym, że włosy stanęły mi dęba, gdy zobaczyłem twój kod, ale nie powiem, bo mi właśnie powypadały, no i jak pomyślę i cofnę się do swoich początków, to też nie było super, więc tego jednak nie powiem
Spytam więc, czy poniższą linijkę:
"robiłeś" metodą copy/paste? [pytanie retoryczne] Jeżeli zmienisz w takiej jednej odpowiedniej linijce i = 1 na i = 0, pomimo innych "niedociągnięć" będzie AC
Witam, oto mój kod. Testowałem go wiele razy dla różnych wartości i większej ilości zmiennych ale SPOJ wykazuje, że odpowiedź jest zła. Przeczytałem dokładnie zadanie i temat, a odpowiedzi dla siebie nie znalazłem
#include <iostream>
using namespace std;
int main()
{
int t,n,srednia,a,licznik,*tablica,elm;
int roznica,roznica_elm;
cin>>t;
for(int i=0;i<t;i++)
{
cin>>n;
tablica=new int [n];
int *w=tablica;
licznik=0;
srednia=0;
for (int j=0;j<n;j++)
{
cin>>a;
if(a!=0)
{
*w=a;
w++;
licznik++;
srednia=srednia+a;
}
}
srednia=srednia/licznik;
for(int j=0;j<n;j++)
w--;
elm=1;
if((*w-srednia)<0)
roznica_elm=-(*w-srednia);
else
roznica_elm=*w-srednia;
for(int j=0;j<n;j++)
{
if((*w-srednia)<0)
roznica=-(*w-srednia);
else
roznica=*w-srednia;
if(roznica<roznica_elm)
{
roznica_elm=roznica;
elm=j+1;
}
w++;
}
cout<<elm<<endl;
delete [] tablica;
}
}
Także mam jeden mały problemik z ustawieniem wskaźnika z końca na początek tablicy. Dopiero zaczynam z tymi wskaźnikami, programowanie strukturalne z listami udało mi się na pierwszym semestrze studiów zaliczyć bez problemu chociaż wiedzę o wskaźnikach tylko liznąłem i dopiero teraz zaczynam się tym poważnie interesować i chcę to jak najlepiej zrozumieć i zapamiętać by móc odpowiednio optymalizować swoje algorytmy i programy.
Ustawiam wskaźnik na pierwszy element tablicy poprzez int *w=tablica; Zwiększam wskaźnik przy pomocy w++; gdzie adres skacze o 4 i wskaźnik wskazuje na kolejne elementy. Po wczytaniu wszystkich elementów tablicy chciałbym wskaźnik ustawić po raz kolejny na 1 element tablicy ale komenda int *w=tablica; nie działa (ponowna deklaracja *w), a *w=tablica; również wyrzuca mi błąd (konwersja *int na int)
Bardzo byłbym wdzięczny o instrukcje/wiedzę która pomogłaby mi w moim problemie, z góry dziękuję serdecznie za poświęcony czas i uwagę
Dobra znalazłem mój arcybanalny błąd którym było wypisanie NUMERU ELEMENTU zamiast samego elementu. Cieszę się, że to nie algorytm okazał się być nieprawidłowy czy źle wykonany, a tylko i wyłącznie taki drobny szczególik. Pozdrawiam i życzę miłego weekendu
Kolejna rzecz co do tego programu to właśnie różnica pomiędzy 2.8, a 2. Zmienna średnia musi być typem double. Testem może być : srednia=2.8; input: 1 input: 2 2 3 output : 3
Trochę przesadziłem z tymi moimi włosami, sprawdziłem i okazało się, że tylko osiwiałem
Może nie tragiczny, w końcu twój kod uzyskał AC, ale bardziej zaawansowany koder zobaczyłby wiele rzeczy, które zrobiłby inaczej - prościej, np.: 1. zamiast int t = 0; int k = 0; można int t, k; //nie trzeba ich zerować, bo zostaną za chwilę "nadczytane" nową wartością gdybyś chciał nadać wartość początkową, to można: int t = 0, k = 999; 2. zamiast: float min = 0; float srednia = 0; float suma = 0; float roznica = 0; //nie jest używana można:
double min, //nie trzeba zerować
srednia, //nie trzeba zerować
suma; //nie trzeba zerować w tym miejscu, tylko w pętli
//gdy nie wiesz czemu, używaj double a nie float 3. zamiast [w pętli]: suma = 0; srednia = 0; //to jest tu zupełnie niepotrzebne k = 0; //to jest tu zupełnie niepotrzebne cin >> k; można: double suma = 0; // wtedy nie potrzebna deklaracja zmiennej suma wcześniej cin >> k; 4. tablica2 nie jest potrzebna, można "na bieżąco" przeglądać pierwszą tablice i "na bierząco" od razu zapamiętrywać pozycję [i] minimum. Skoro tak, to spora dalsza część programu będzie zbędna. Duża część zmiennych [większość] mogłaby być typu int, a tylko napewno średnia musi być typu rzeczywistego, np double.
Po przeanalizowaniu wydaje mi się to jasne. Gdy piszemy int w to nie mamy do czynienia już ze wskaźnikiem tylko zmienną typu liczby całkowitej o nazwie *w która ma wartość danego elementu tablicy. Tak mi się wydaje. Z drugiej strony gdy adres wskaznika ma przypisany adres pierwszego elementu tablicy (int *w,tablica; tablica=new int [cos]; w=tablica;) to wypisujac *w to pobieramy wartosc z pierwszego elementu tablicy a inkrementujac adres wskaznika dla inta, jego adres zwieksza sie o 4 czyli *w pobiera wartość z następnego elementu tablicy. Dobrze to rozumiem ?
Po przeanalizowaniu, twojej analizy, wydaje mi się, że to jest jednak, u Ciebie, nadal nie zupełnie jasne
Poprawione twoje zdanie/myśl: Gdy piszemy: int w; to deklarujemy zmienną typu int o nazwie w, która nie ma nic wspólnego ani z wskaźnikiem ani z tablicą. Jest po prostu [sobie] zwykłą zmienną, która "przechowuje" [zawiera, "pamięta"] dowolną wartość liczbową w zakresie int [-2^31, +2^31-1].
Poprawione twoje zdanie/myśl: ... gdy wskaznik ma przypisany [zawiera/"pamięta"] adres pierwszego elementu tablicy: int *w, *tablica; tablica = new int [cos]; //po co tak?*/ a jeżeli już tak, to linię wcześniej *tablica w = tablica; to wypisujac *w pobieramy wartosc pierwszego elementu tablicy, a inkrementujac wskaznik ++w, typu int, jego wartość [przechowywany/wskazywany adres] zwieksza sie [dla typu int o 4] czyli *w [pobiera] jest wartością następnego elementu tablicy.
W tym wypadku, tak naprawdę, wskaźnik nie różni się specjalnie od indeksu tablicy, więc jak masz kłopoty ze zrozumieniem działania wskaźników, to może na razie zapomnij o wskaźnikach a używaj po prostu zwykłej tablicy i jej indeksów. Ewentualnie poczytaj w "dobrej" książce rozdział poświęcony wskaźnikom.
W takim razie, po co są w ogóle wskaźniki, jeżeli są tym samym co indeks tablicy? 1. Czasami wskaźnik/i upraszczają zapis kodu. 2. Gdy tablica jest dwu i więcej wymiarowa i gdy koder wie jak poszczególne elementy takiej tablicy "siedzą/leżą" w pamięci i gdy koder wie co robi ..... to czasami używa wskaźników. 3. Użycie wskaźników czasami skraca znacząco kod i ukrywa/szyfruje jego faktyczne działanie [gdy brak komentarzy] przed okiem laika. [to taki trochę żart] 4. Koder, który liznął assemblera lub który orientuje się jak "to" działa od środka [procesor, pamięć, język maszynowy/assembler] nie powinien mieć problemu ze zrozumieniem i stosowaniem wskaźników lub z rezygnacji z ich usługi. 5. Gdy koder/programista używa tablic i struktur dynamicznych [alokowanych dynamicznie], wtedy wskaźniki mogą być/[są] niezastąpione.
PS Uważam jednak, że więcej zyskasz czytając porządny opis tego wszystkiego, niż to co ja napisałem. Jeżeli jednak spodobał Ci się mój opis, domagam się serduszek w dużej ilości Z góry dzięki
*/ Zmienna tablica jest już wskaźnikiem, więc nie jest potrzebny następny wskaźnik: w W takim przykładzie możemy zadeklarować tablicę statycznie: int *w, tablica[coś];
Dobra, już rozumiem. Zmyliła mnie nazwa zmiennej. Rozjaśniła mi wszystko Twoja wypowiedź z tą deklaracją zwykłej zmiennej. Haha wiem trochę o tych pamięciach procesora, sam programuje płytki MSP430 na laboratoriach z Architektury Komputerów więc ogólną koncepcję liznąłem. Wskaźniki są niezastąpione według mnie choćby w celu użycia ich w strukturach danych typu lista, drzewo binarne no i nieraz znacznie skracają czas działania algorytmu gdzie zamiast właśnie jadąc po indeksach komputer przeskakuje po andresach zmiennych elementów tablicy.
Przez tego if'a SPOJ nie chce zaliczyć mi zadania?
Wcześniej obliczona minimalna odległość wskazuje na liczbę najbliższą średniej, którą można przedstawić w postaci srednia-mini lub srednia+mini. Ponieważ nie wiadomo czy najpierw wprowadzona została 5 czy 15, ten if ma kolejno sprawdzić wszystkie elementy tablicy i znależć pierwszą liczbę której odległość od średniej jest równa mini. Albo 5 albo 15, nie ma różnicy, bo są tak samo oddalone od średniej
Nie wiem, czemu SPOJ nie zalicza Ci tego kodu, ale mi też się twój kod nie podoba.
Gdy używasz zmiennej typu double unikaj "dokładnego" jej porównywania --> "=="
Taką funkcjonalność [3 x if] ma funkcja fabs(...) [nie mylić z abs]
Czy to powoduje WA? nie wiem i w tej chwili nie ma tego jak sprawdzić.
=============== JUŻ MOŻNA =============== Faktycznie poniższa linijka jest błędem - błędy zaokrąglenia liczb zmiennoprzecinkowych:
Popraw to na:
if (odl[y] == mini)
Ale i tak twój kod dalej będzie mnie straszył i nawiedzał po nocach Powyższa poprawka to tylko taka proteza - minimum na AC. Poprawić możnaby i należało dużo więcej.