Wątek zablokowany 2013-11-14 04:27 przez furious programming.

Poprawki w programie.

0

Witam, w moim programie jest wszystko w porządku, choć nie działa on wg wytycznej, chciałbym by mi ktoś powiedział jak mogę go niewielkimi zmianami przerobić tak, by działał. Na _out powinno być kolejno

48 x 12 = 576
48 x 32 = 1536
52 x 48 = 2496
92 x 32 = 2944
92 x 42 = 3864
136 x 32 = 4352.

Program ten ma policzyć optymalne pole powierzchni, co jest moim głównym zadaniem, a pobocznym-postać najbardziej zbliżona kwadratowi. Zmiany chciałbym wprowadzić w funckji calculate. Już w abs nie chcę się bawić. Kosmetyka... Głównie chodzi o if z linii 82.
Pozdrawiam.

Plik _in zawiera:

6  - ilość danych do obliczeń
1   dane
15 
22 
29 
36 
43
#include <fstream>
//#include <cstdio>
//#include <iostream>



using namespace std;

class Containers
{
public:
    long long int t[100], t_stack[100],size,count;
    //int l_con,w_con,l_place[100000],w_place[100000],l_breaks,w_breaks,min_substr[100000],result_width[100],result_lenght[100],result_field[100];
    int l_con,w_con,l_place,w_place,l_breaks,w_breaks,min_substr,result_width[100],result_lenght[100],result_field[100];
    Containers()
    {
        count=0;        //zerowanie licznika
        l_con=40;       //dlugosc kontenera  - lenght
        w_con=8;        //szerpkosc kontenera - width
        size=0;         //zerowanie rozmiaru tablicy danych wczytywane z pliku
        l_breaks=2;      // odstep pomiedzy wierszami
        w_breaks=4;         // odstep pomiedzy kolumnami
        for(int i=0; i<100; i++)        // zerowanie tablic
        {
            t[i]=0;             // zerowanie tablic
            t_stack[i]=0;
            //l_place[i]=0;
            //w_place[i]=0;
            //min_substr[i]=0;
            result_width[i]=0;
            result_lenght[i]=0;
            result_field[i]=0;      //koniec zerowania
        }
    }

    void addnew(int x)          //dodawanie wartosci do tablicy w klasie
    {
        t[count]=x;             // zwykly licznik
        count++;
    }

    void calc_stacks()          // policz ilosc stosow - dzielenie ilosci kontenerow  /5 i %5.
    {
        for (int i = 0; i < size; i++)
        {
            int wynik=t[i]/5,rest=t[i]%5;       //zwracanie wyniku do tablicy
            t_stack[i]=wynik;
            if(rest>0)                          //jesli reszta wieksza od 0,
            {
                t_stack[i]++;                   //to zwieksz stos o 1.
            }
        }
    }
    void calculate()                            //liczenie ilosci wierszy, kolumn i pola
    {
        //int k,tmp2,n=0,tmp3=900000000;
        int k,tmp2,tmp3=900000000;
        for(int i=0; i<size; i++)
        {
            for(int j=1; j<=t_stack[i]; j++)
            {
                k=t_stack[i]/j;
                //cout<<"i="<<i<<"\tj="<<j<<"\tt_stos[i]="<<t_stos[i]<<"\tk="<<k<<endl;
                tmp2=t_stack[i]%j;
                if(tmp2!=0) k++;
                l_place=(l_con*k)+(w_breaks*(k+1));
                w_place=(w_con*j)+(l_breaks*(j+1));
                //cout<<"l_place[n]="<<l_place[n]<<"\tw_place[n]="<<w_place[n]<<endl;

                if(l_place>w_place)
                {
                    min_substr=l_place-w_place;
                // cout<<"if wyniki1[n]="<<wyniki1[n]<<"\tl_place[n]="<<l_place[n]<<"\tw_place[n]"<<w_place[n]<<endl;
                }
                else
                {
                    min_substr=w_place-l_place;
                    //cout<<"else wyniki1[n]="<<wyniki1[n]<<"\tl_place[n]="<<l_place[n]<<"\tw_place[n]"<<w_place[n]<<endl;
                }


                if(min_substr<=tmp3)
                {
                    tmp3=min_substr;
                    result_width[i]=w_place;
                    result_lenght[i]=l_place;
                    //cout<<"l_place[n]="<<l_place[n]<<"\tw_place[n]"<<w_place[n]<<endl;
                }

                //n++;

            }
            result_field[i]=result_width[i]*result_lenght[i];
                    //cout<<"w3="<<wynik3[i]<<"\tw1="<<wynik1[i]<<"\tw2="<<wynik2[i]<<endl;
            tmp3=900000000;
            //n=0;
        }
    }

    ~Containers();
};

Containers *containers = new Containers();      // nowy obiekt klasy containers

void load();
void save();

int main()
{
    load();
    containers->calc_stacks();
    containers->calculate();
    save();
    return 0;
}

void load()  //wczytywanie danych, wg zadania
{
    int a=0,b=0;
    FILE *f;
    f=fopen ("_in.txt","r");
    fscanf(f,"%d",&a);
    containers->size=a;  //pobiera ilosc przypadkow wg przykladu napisanym w zadaniu: 6
    for(int i=0; i<a; i++)
    {
        fscanf(f,"%d",&b);
        containers->addnew(b);  //nowy obiekt w klasie ----------------------
    }
    fclose(f);
}

void save() //zapis do pliku wyniku w postaci  x * y = z gdzie x>y
{
    FILE *f;
    f=fopen("_out.txt","w");
    for(int i=0; i<containers->size; i++) //petla zapisujaca
    {
        if(containers->result_width[i]>containers->result_lenght[i])
            fprintf(f,"%d x % d = %d\n",containers->result_width[i],containers->result_lenght[i],containers->result_field[i]);
        else
            fprintf(f,"%d x % d = %d\n",containers->result_lenght[i],containers->result_width[i],containers->result_field[i]);
    }
    fclose(f);
}

dodanie znaczników <code> - fp

0

Nie wiem czym tobie zawadził abs() ale możesz użyć tego:

min_substr=l_place>w_place?l_place-w_place:w_place-l_place;

Cały kod to jedno wielkie WTF.
Może wyjaśnij o co z tym wszystkim chodzi bardziej dokładnie, całość da się zrobić znacznie szybsze i znacznie bardziej kompaktowe.

0

Hehe może i ten "kod to jedno wielkie WTF", ale ja wiem o co w nim chodzi i sam go pisałem :). Wiem, że jakość nie jest powalająca (można się zmieścić w 80 linijkach...). Cóż dopiero się uczę :P. Ten kod ma dzielić ilość rzeczy modulo 5 i dzielić je w ten sposób na stosy, następnie ma sprawdzać różne kombinacje ich ustawienia, potem ma znaleźć taką kombinację, która będzie dawała jak najmniejsze pole powierzchni, drugim, mniej ważnym kryterium jest by ten "plac" był jak najbardziej zbliżony do kwadratu. Powiedz mi jak dokładnie działa ta linijka? Na cplusplus.com czytałem o operatorze "?", mógłbyś to lepiej wytłumaczyć?

0

Twoje wyjaśnienie to jeszcze większe WTF, może spróbuj wytłumaczyć po kolei.
Mam wytłumaczyć lepiej niż na cplusplus.com - nie sądzę że jest to możliwe.

0

Dobra a powiedz co dokładnie mam Ci wytłumaczyć? :) Jeszcze dokładniej? :O Naprawdę nie wiem czego jeszcze nie powiedziałem.

0

"Ten kod ma dzielić ilość rzeczy modulo 5" - ilość_rzeczy%5 - to po kiego takie wielkie bydle!?
"i dzielić je w ten sposób na stosy" - słyszałem o dzieleniu włosa na czworo ale o dzieleniu liczby na stosy - pierwszy raz słyszę.
"następnie ma sprawdzać różne kombinacje ich ustawienia" - jakie kombinacje? kogo ich? jak sprawdzać? po kiego?
"potem ma znaleźć taką kombinację, która będzie dawała jak najmniejsze pole powierzchni" - za kombinacje dają czasami kilka lat, ale żeby za kombinacje dawali pole powierzchni ... co palisz?
"drugim, mniej ważnym kryterium jest by ten "plac" był jak najbardziej zbliżony do kwadratu" - jaki plac i co ma do wszystkiego powyżej?

0

Takie wytyczne to tak musi być. Swoją drogą czytająć Twojego posta prawie się popłakałem. :D a co jaram? LM forward (nie reklamuje, żeby nie było :) :).
A teraz rozwiewam Twoje wątpliwości/pytania :)...
ad 1. masz podaną ilość pojemników, na jednej kupie może być tylko pięć.
ad 2. wiem, to są takie "inne" stosy :P może pseudostosy, ale jednak stosy.
ad 3. tak, tak za kombinacje można sobie posiedzieć... :D nie kombinacje a możliwości, czyli jedną z możliwości, która daje najmniejsze pole powierzchni.
ad 4. skoro liczymy pole powierzchni, w dodatku prostokąta to chyba on ma jakieś pole no nie? :D teraz ja powinienem się zapytać co jarasz... :D

0

Czyli program stosy kup rozkłada po pojemnikach o prostokątnej powierzchni licząc przy tym kwadraturę kupy?
Naprawdę z twojego opisu nic nie da się zrozumieć.

0

@Pitrek1991 Bo widzisz, my w przeciwieństwie do ciebie NIE WIEMY jakie jest POLECENIE tego zadania. Nie wiemy jakie sa dane wejściowe i co powinno być na wyjściu. To tak jakbyś napisał:
"Mój program dostaje na wejściu 1 i powinien wypisać na wyjście 2 a wypisuje 3. Gdzie jest bląd? Może pomyliłem się we wzorze na głebokość? A może źle zaimplementowałem kolejkę? Albo źle wybieram kombinacje?"
Czy wiedziałbyś o co chodzi gdybyś przeczytał takie coś jak powyżej? Nie? Twoje posty wyglądają dokładnie tak...

0

Mea culpa, macie rację, ale zrozumcie... nie wiem jak to zrobić, a samemu nic nie wymyślę. Nie chciałbym by mój prowadzący to przeczytał.... :( Chcę się tego nauczyć, dlatego to co napisałem, było samodzielne. Dalej nie wiem jak tę funkcję poprawić... Dzięki za wyrozumiałość.. I mam nadzieję że ten temat po rozwiązaniu będzie można usunąć...

Kontenery w porcie gromadzone są na specjalnym placu terminalu. Aby umożliwić
dowóz kontenerów różnymi drogami (kolej, samochody, żegluga śródlądowa) postanowiono,
że najlepszym wyjściem będzie budowa takiego placu przy ujściu rzeki. Takie rozwiązanie
ma niestety pewne wady. Grunt jest tam bardzo grząski, a jak wiadomo budowanie na
stabilnym gruncie jest znacznie tańsze. Oznacza to, że plac przeznaczony na kontenery nie
powinien być większy, niż jest to potrzebne.
Pojedynczy kontener ma 40 stóp długości i 8 stóp szerokości. Kontenery mogą być położone
jeden na drugim, przy czym wysokość stosu nie może przekraczać pięciu kontenerów. Takie
stosy są następnie układane w rzędy. Pomiędzy poszczególnymi stosami oraz pomiędzy
zewnętrznym stosem, a granicą placu (wzdłuż dłuższej ściany) musi zostać zachowana
odległość 2 stóp. Analogiczne odległości liczone wzdłuż krótszego boku kontenera muszą
wynosić 4 stopy. Wszystkie kontenery muszą być ułożone w ten sam sposób. Powyższe
ograniczenia są oczywiście narzucane przez sposób przenoszenia kontenerów, gdyż
wykonujące to zadanie dźwigi muszą mieć miejsce, aby schwycić ładunek i nie mogą się
obracać.
Plac ma mieć kształt prostokąta. Zadanie polega na określeniu optymalnego rozmiaru placu.
Najważniejszym kryterium jest jego wielkość, kolejnym kształt jak najbardziej zbliżony do
kwadratu. Poniższy rysunek pokazuje plan dla 8 stosów. Ustawienie dwóch rzędów po cztery
stosy prowadzi do całkowitej powierzchni 92 × 42 = 3864 .
(jedynki symbolizują kontenery a "_" odstępy)
1_1
1_1
1_1
1_1
Wejście
W pierwszej linii znajduje się jedna liczba całkowita dodatnia, nie przekraczająca 100,
odpowiadająca liczbie przypadków testowych.
Każdy przypadek testowy zawiera jedną liczbę całkowitą dodatnią n ( 12
n ≤ 10 ), wymaganą
pojemność placu wyrażoną w liczbie kontenerów.

Wyjście
Dla każdego przypadku testowego powinna być wyprowadzona jedna linia zawierająca
długość (a), szerokość (b, b<=a) oraz powierzchnię placu. Przykładowy, choć nie wymagany
format widoczny jest poniżej
.

Dla danych wejściowych:

6
1
15
22
29
36
43

poprawną odpowiedzią jest:

48 x 12 = 576
48 x 32 = 1536
52 x 48 = 2496
92 x 32 = 2944
92 x 42 = 3864
136 x 32 = 4352

0
  1. wczytujesz K - ilość kontenerów
  2. obliczasz ilość stosów S=(K+4)/5
  3. rozkładasz S na iloczyn liczb pierwszych dzieleniem
  4. dopóki w iloczynie jest mniej niż dwie liczby dodajesz do listy jedynki
  5. dalej dzielisz listę na dwie listy np backtrackingiem.

Zostaw też te otwierania plików, program ma wyglądać następująco:

#include <stdio.h>

int main()
  {
   unsigned T,K,W,H;
   scanf("%u",&T);
   while(T--)
     {
      scanf("%u",&K);
      // tu wyliczasz W,H
      printf("%u x %u = %u\n",W>H?W:H,W>H?H:W,W*H);
     }
  }

Zaś dla testów z konsoli odpalasz program:
kontenery.exe <_in.txt >_out.txt
** .exe można pominąć *

0

@_13th_Dragon, dzięki, pomysł niezły, optymalizacja też. Niestety według polecenia musimy wczytywać i zapisywać dane.. Chciałbym przerobić tę moją funkcję tak, by na _out było to co w poleceniu... wiem że potrzeba na to raptem zmienić w 3 linijkach by działało tak jak powinno, ale nie wiem co... Jak widać w komentarzach jest opis, lub zakomentowane są linie, które zmieniłem, lub usunąłem... co z tym if'em?

0

@Shalom to nie jest mój wymysł. Ja się dostosowałem...

1
Pitrek1991 napisał(a):

no spoko, tyle że ja nie chcę wprowadzać tutaj nie wiadomo jakich
zmian... Zrozumcie. Chcę tylko by wyświetlał na oucie to samo co jest
napisane w zadaniu...

Nie, to ty musisz zrozumieć: - to co podałeś nadaje się wyłącznie na kosz, od ciebie wykładowca chciał przynajmniej tyle:

#include <stdio.h>

int main()
  {
   unsigned T,N,K,W,H,by,bv,cv,x,y;
   scanf("%u",&T);
   while(T--)
     {
      scanf("%u",&N);
      K=(N+4)/5;
      for(bv=2*(K*44+4)*(K*10+2),by=K+1,y=1;y<=K;++y)
        {
         x=K/y;
         if(y*x==K)
           {
            cv=(y*44+4)*(x*10+2);
            if(bv>cv)
              {
               bv=cv;
               by=y;
              }
           }
        }
      H=by*44+4;
      W=K/by*10+2;
      printf("%u x %u = %u\n",W>H?W:H,W>H?H:W,W*H);
     }
   return 0;
  }

Ale wystarczy sprawdzić znacznie mniej wartości rozwiązując system równań:

K = y*x
4 + 44*y = 2 + 10*x

W wyniku otrzymujesz:

y=(sqrt(1+440*K)-1)/44;
x=(sqrt(1+440*K)+1)/10;

I teraz wystarczy sprawdzić tylko 4 wersje.

0

@_13th_Dragon załamę się... wiem, że można lepiej, inaczej i w ogóle, ale kuźwa mi teraz nie zależy na tym by ten kod pisać od nowa... Bo nie mam na to czasu, w czwartek chcę to wysłać, a nadal nic konstruktywnego, o co Was prosiłem nie otrzymałem... chodzi o tego jednego if'a, nic więcęj... Ja się już poddaję...

2

@Pitrek1991 szkoda mi do ciebie słów. Wyobraź sobie że przychodzi do ciebie ktoś z gównem na talerzyku i nalega żebyś zrobił mu z tego tort. Nie, nie może wyrzucić gówna i upiec nowego tortu bo ktośtam widział ten talerzyk. My ci tutaj mówimy że zrobiłeś to po prostu źle (vide: nasrałeś na talerzyk) a ty uparcie twierdzisz że wystarczy jakaś mityczna malutka zmiana która sprawi że będzie dobrze (może posypać g**no rodzynkami?).

0

Super. MOŻE I g**no ALE MOJE. Ile razy to samo mam pisać? Nie rozumiecie? Co w tym takiego trudnego. Określiłem jasno o co mi chodzi. NIE PROSIŁEM O PONOWNE NAPISANIE PROGRAMU TYLKO O JEGO poprawę. Tak by na oucie było to co trzeba. Macie ambiwalentne podejście z tą Waszą pomocą. Cóż chyba pogodzę się z tym, że na tym forum nikt nie potrafi pomóc... Pozdrawiam.

0

Proszę admina o usunięcie tego tematu. Dziękuję z góry.

2

Niestety po raz kolejny początkujący nie otrzymuje pomocy o jaką prosi... Ehh...

Z racji tej, że już sypią się nieco obraźliwe słowa i zwroty, a nawet wyzwiska - wątek zamykam;
Może to niektórych nauczy odpowiadania na pytania, a nie usilnego wmawiania własnych rozwiązań, a przede wszystkim cierpliwości, której jak widać nie jednemu brakuje.

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