• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

SPOJ Tablica

VPS Starter Arubacloud
+1 głos
2,793 wizyt
pytanie zadane 20 czerwca 2016 w C i C++ przez krzemionskyy Użytkownik (630 p.)

Witam,

Rozwiązuję zadanko ze spoja: http://pl.spoj.com/problems/TABLICA/

Dowaliłem rozwiązanie uwzględniające wszelkie możliwe kombinacje wpisania spacji, ma ktos pomysł co tu może być njie tak? Sędzia zwraca błędna odpowiedź.

Pozdrawiam.

 

#include <iostream>
#include <cstdlib>
#include <cctype>

using namespace std;

string arrayCleaner(string num){
    
    string temp;
    
    for(int i = 0; i < num.length(); i++){
        
        if((num[i] == ' ') && (num[i+1] == ' ')){
            
            temp += "";
        }
        else temp += num[i];
    }
    if(temp[0] == ' ') temp.erase(0,1);
     
    for(int i = temp.length() - 1; i >= 0; i--){
        
        if(isdigit(temp[i])){
            
            break;
        }
        else temp.erase(i,1);
    }
   
    return temp;
}

int arrayLength(string num) {

    int counter = 1;

    for (int i = 0; i < num.length(); i++) {
        if (num[i] == ' ') {

            counter++;
        }
    }

    return counter;
}

int * arrayMaker(string num) {

    string temp = "";
    int j = 0;

    int counter = arrayLength(num);

    int * array = new int [counter];

    for (int i = 0; i < num.length(); i++) {
        
        if (num[i] != ' ') {

            temp += num[i];

            if (i == (num.length() - 1)) {

                array[j] = atoi(temp.c_str());
            }
        }

        if (num[i] == ' ') {

            array[j] = atoi(temp.c_str());
            j++;
            temp = "";
        }
    }

    return array;
}

void deleteArray(int * tab) {

    delete [] tab;
}

int main() {

    string number, str="";
    int * t;

    while (getline(cin, str)) {

        number = arrayCleaner(str);
        
        t = arrayMaker(number);

        for (int i = 0; i < arrayLength(number); i++) {

            cout << t[arrayLength(number)-1-i];
            if(i != (arrayLength(number)-1)) cout << " ";         
        }
        cout << endl;

        deleteArray(t);
    }
    return 0;
}

 

komentarz 22 kwietnia 2018 przez koniak20 Początkujący (390 p.)
#include <iostream>

using namespace std;

int main()
{
    string wyraz;
    getline(cin,wyraz);
    int dl=wyraz.length();
    int p=dl-1,g=dl-1;
    int k=0;
    while(wyraz[k]!=' ')
    {
        k++;
    }
     while(p!=k)
    {
        if(wyraz[p]==' ') p-=1;
        while(wyraz[p]!=' ')

        {
            p--;
        }
        for (int i=p+1; i<=g; i++)
        {
            cout<<wyraz[i];
        }
        cout<<" ";
        g=p-1;
    }
    for (int i=0; i<k; i++)
        {
            cout<<wyraz[i];
        }

    return 0;
}

Trochę odkopuje temat ale co sądzicie o takim rozwiązaniu?

2 odpowiedzi

+2 głosów
odpowiedź 20 czerwca 2016 przez MetRiko Nałogowiec (37,110 p.)
wybrane 21 czerwca 2016 przez krzemionskyy
 
Najlepsza

Widzę, że próbowałeś rozdzielać dane pomiędzy spacjami (czyt. stworzyłeś prosty parser). Myślę jednak, że nie potrzebna jest taka zabawa.. tak samo jak dbanie o to czy na wejściu jest gdzieś jakiś nadmiar spacji.. to nie ma sensu skoro w zadaniu jest powiedziane, że "Na wejście programu podana zostanie pewna nieokreślona, ale niewielka ilość liczb całkowitych rozdzielonych spacjami.". Czyli kombinowanie z niepoprawnie wprowadzonymi danymi nie ma sensu.. ponieważ zawsze dane będą podane w takiej samej postaci jak opisano w zadaniu. Zatem przy wczytywaniu danych wystarczy zwykły cin.
Mój sposób na rozwiązanie zadania polega na użyciu wskaźnika i zwykłej tablicy statycznej.. gdyby tablica była za mała (zadanie wywali błąd związany z przekroczeniem rozmiaru tablicy) można zwiększyć jej rozmiar o np. 100.
Moje rozwiązanie:

#include <iostream>
using namespace std;

int main()
{
    int tab[100];
    int *p=tab;
    while(cin>>*p) p++;
    while(p>tab) { p--; cout<<*p<<" "; }
}

komentarz 21 czerwca 2016 przez krzemionskyy Użytkownik (630 p.)
Ciekawe rozwiązanie, no rzeczywiście podszedłem do tego zbyt "szeroko". W każdym razie napisalem cos podobnego i przeszło ; )
Pozdrawiam ;)
komentarz 17 kwietnia 2017 przez BinaryMan Stary wyjadacz (12,620 p.)
Witam !
Mógłby ktoś wyjaśnić mi to rozwiązanie ?
komentarz 2 maja 2022 przez Oscar Nałogowiec (29,290 p.)
edycja 2 maja 2022 przez Oscar

W linii 8 wczytujemy liczby w wejścia do tablicy, przesuwając wskaźnik, który pierwotnie wskazuje na pierwszy element, a w następnej linii wypisujemy liczby poczynając od miejsca gdzie wskazuje wskaźnik i go cofamy aż wskaże na początek tablicy.

Oczywiście można to samo zapisać z indeksowaniem tablicy:

#include <iostream>
using namespace std;
 
int main()
{
    int tab[100];
    int idx=0;   ///< tym razem zwykły int do indeksowania
    while(cin>>tab[idx]) idx++;
    while(idx>0) { idx--; cout<<tab[idx]<<" "; }
}

W pętli wczytującej wykorzystano tu fakt, że << i >> to operatory, podobnie jak + czy - i konstrukcja cin>>x jest wyrażeniem i zwraca wynik, który można użyć w programie. Akurat ze strumieniami jest to nieco skomplikowane, ale sprowadza się do tego, że pierwsza pętla się skończy gdy skończą się dane

 

Rozwiązanie będzie działać, jednak nie wiadomo czy 100 jest wystarczająco niewielkie, jak określono ilość danych na wejściu w treści zadania.

0 głosów
odpowiedź 20 czerwca 2016 przez niezalogowany
nie będę tego analizować, pomogę Ci tylko. Weź wpisz do dynamicznej tablicy wszystkie liczby i wyświetl je od tyłu po czym zrób spacje. i nie kombinuj tylko zrób tak jak Ci napsiałem
komentarz 1 maja 2022 przez Paweł110 Nowicjusz (140 p.)

Witajcie, jestem bardzo początkujący i domyślałem się, że można rozwiązać to zadanie tablicą, ale dlaczego takie rozwiązanie nie działa? Przez to, że wyjście  to string, a nie int?

#include <iostream>
#include <string>

using namespace std;

int main()
{
    string liczby;
    string odwrl;

    getline(cin,liczby);
    int dlugosc=liczby.length();
    for(int i=dlugosc-1; i>=0; i=i-2)
        {
           odwrl+=liczby[i];
        }
    for(int i=0; i<=dlugosc; i++)
        {
           cout<<odwrl[i]<<" ";
        }

    return 0;
}

 

komentarz 2 maja 2022 przez Oscar Nałogowiec (29,290 p.)

Ponieważ czytasz z wejścia linię i odwracasz w niej kolejność znaków. Oczywiście,  może być liczba (ciąg znaków). Jeśli wczytasz "123" to wypiszesz "321" a chyba nie o to chodzi. Akurat podany w zadaniu przykład zostanie prawidłowo obsłużony, ale to tylko dlatego, że występują tam jedynie jednocyfrowe liczby. Gdyby na wejsciu było "12 23 34" twój program wypisze "43 32 21" a powinien "34 23 12".

Z zadaniu nie podano, że "ilość liczb" jest jakoś podana na początku (jak w większości innych zadań), a jedynie podano, że jest niewielka. Tablica wymaga jednak znajomości jej rozmiaru. Przypuszczam że autorowi zadania chodziło o algorytm rekurencyjny. Użycie jakiś struktur dynamicznych - list, wektorów itp eliminowało by warunek by ilość (chyba powinno być liczba - ale "liczba liczb" brzmi głupio) danych na wejściu była niewielka. W sumie limit pamięci wynosi ~ 1GB, więc liczb zmieści się całkiem sporo. Przetworzenie tylu  w czasie 1s może być trudne.

komentarz 2 maja 2022 przez Paweł110 Nowicjusz (140 p.)

Dzięki za podpowiedź. Napisałem wg wskazówek takie cos:

#include <iostream>


using namespace std;

int main()
{
    int tablica[101];
    int liczba;
    int k=0;
    while(cin>>liczba)
        {
           tablica[k]=liczba;
           k++;
        }
        for(int j=k-1; j>=0; j--)
        {
            cout<<tablica[j]<<" ";
        }

    return 0;
}

Jednak mam problem ze swoim kompilatorem. Podając w pętli while pobranie znaku jako warunek, moj kompilator sobie z tym nie radzi, a SPOJ akceptuje. Po prostu po wprowadzeniu wyrazów i wciśnięciu enter program zachowuje się jakby nadal czekał na jakies dane. Wisi w powietrzu. Jest jakies proste rozwiązanie? Code::Blocks 20.03

komentarz 2 maja 2022 przez Oscar Nałogowiec (29,290 p.)
Ty wprowadzasz z klawiatury, SPOJ po prostu przekierowuje odpowiednie pliki testowe na wejście programu. Plik na dysku na swoją wielkość, a więc i koniec, klawiatura nie ma końca sama z siebie. Trzeba użyć metody na zasygnalizowanie końca pliku z klawiatury. Pod DOSem to było Ctrl-Z, pod Linuxem Ctrl-D.
komentarz 2 maja 2022 przez Paweł110 Nowicjusz (140 p.)
A jest jakiś sposób, żeby napisać program, który pobiera dane do momentu, do kiedy przed naciśnięciem entera nie wprowadzimy żadnych danych?

wprowadzenie danych:

1 Enter

2 Enter

itd

(nic nie wprowadzono) Enter

i w tym momencie wykonuje się dalsza cześć programu
komentarz 2 maja 2022 przez Oscar Nałogowiec (29,290 p.)
Dla operatorów >> wszystkie białe znaki (odstęp, tabulacja, nowa linia) są jednakowo ważne. Musiałbyś przejść na czytanie po linii (getline) i wychodzić w przypadku odczytania pustej linii, ale nie wiadomo czy SPOJ takie coś łyknie. Pamiętaj, że tam nie siedzi ktos, kto testuje te programy z klawiatury.

Podobne pytania

+1 głos
1 odpowiedź 198 wizyt
pytanie zadane 18 lipca 2022 w Java przez Ada3141592654 Początkujący (270 p.)
0 głosów
1 odpowiedź 437 wizyt
0 głosów
1 odpowiedź 565 wizyt
pytanie zadane 21 sierpnia 2019 w C i C++ przez cupoforanges Początkujący (380 p.)

92,452 zapytań

141,262 odpowiedzi

319,085 komentarzy

61,854 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...