1 / 153
Nov 2015
#include <iostream>
#include <cmath>
using namespace std;

int main() {
int a,b,c,d,suma=0;
cin>>a;
for (int i=0;i<a;i++)
{
cin>>b;
for (int i=0;i<b;i++)
{
cin>>c;
suma+=c;
}
d=suma/b;
cout<<d<<endl;
}
	return 0;
}

Witam,
czy jest ktoś w stanie mi pomóc i wskazać błąd jaki popełniłem w zadaniu? SPOJ czepia się błędnej odpowiedzi.
Z góry dzięki

  • created

    Nov '15
  • last reply

    Nov '22
  • 152

    replies

  • 7.6k

    views

  • 49

    users

  • 27

    likes

  • 35

    links

Frequent Posters

There are 152 replies with an estimated read time of 19 minutes.

I SPOJ ma całkowicie rację, że się czepia.
DIY smile
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.

Nie ma za co.

Komentarze, które były pod zadaniem:

2015-12-05 14:14:23
dlaczego kiedy testuje program i wpisuje tą drugą kolejnośc wyskakuje mi 2 a nie 3 i przez to zaliczyc nie moge

2015-03-04 00:20:43 Witold D³ugosz

Bo kolejność jest inna smile

2015-03-03 21:10:24 Bartosz Przyby³ek

W przykładzie w testach 1 i 2 suma jest taka sama, a wyniki są inne.

http://discuss.spoj.com/search?q=%C5%9Brednia%20arytmetyczna

http://pl.spoj.com/forum-old/viewtopic.php?f=1&t=32&hilit=1102&sid=a9fca737a563dbe6c74ec16dce6cbb09152

Odświeżam temat ... Macie pomysł dlaczego poniższy kod nie przechodzi ? Byłbym wdzięczny za wszelkie rady smile Testy różne, różniste przechodzi....

code

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 wink

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 confused

#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;
    }
}

Z góry dziękuje za pomoc !

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ę smile

joy 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 smile

dzięuję za pomoc i przepraszam za Twoje włosy smile

a mógłbym z ciekawości spytać dlaczego ten kod był tragiczny ? smiley jakieś wskazówki na przyszłość ? smile byłbym wdzięczny smile

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

Kod został zaakceptowany =)

Trochę przesadziłem z tymi moimi włosami, sprawdziłem i okazało się, że tylko osiwiałem wink

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.

Chyba tylko tyle wink

pozdrawiam i powodzenia.

Poprawnie:
w = tablica
lub
w = &tablica[0]

w - wskaźnik
*w - wartość "wskazywana" przez wskaźnik w
int *w deklaracja zmiennej wskaźnikowej w

Pozwolę sobie na jeszcze jedną uwagę.

Prawidłowo:

int *w = tablica; /// tu w takim przypadku wystarczyłoby int *w;
pętla [while, for, do]{
   w = tablica;
  ....
}

A poniższy fragment, czy też działa poprawnie [tylko c++] i dlaczego [pytanie retoryczne, ja wiem, ale czy Ty to wiesz] ?

/// int *w = tablica; /// "przenosimy" do środka pętli
pętla [while, for, do]{
   int *w = tablica;
  ....
}

dziękuję za te sugestie smile postaram się je wprowadzić w życie jak najszybciej smile ba...zaraz zabiorę się za poprawienie tego kodu smile Pozdrawiam smile

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 wink

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] wink
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 wink 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.

Pozdrawiam i życzę udanego weekendu =)

8 days later

Strzelałbym, że problem tkwi w tym punkcie smile

if((tab[y]==srednia-mini)||(tab[y]==srednia+mini))

przykład : średnia = 10;
mini = 5;

jeżeli t[0] == 10-5=5 lub t[0]= 10+5=15 to wszystko jedno i to samo, niech będzie moim wynikiem !

5 i 15 to nie to taka sama wartość przyjacielu wink

Do tego zaokrąglij sobie średnią gdy ją liczysz funkcją round.

Pozdrawiam wink

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 grin

Co zmieni zaokrąglenie średniej? worried

Nie wiem, czemu SPOJ nie zalicza Ci tego kodu, ale mi też się twój kod nie podoba. wink

  1. Gdy używasz zmiennej typu double unikaj "dokładnego" jej porównywania --> "=="
  2. 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 wink
Powyższa poprawka to tylko taka proteza - minimum na AC. Poprawić możnaby i należało dużo więcej.