Wczytywanie danych wejściowych SPOJ

0

Witam,

Mam problem otóż chcę wykonać zadanie konkursowe ale mam problem w jaki sposób wczytać dane. Tu podaje jak jest opisane zadanie(SPOJ:
Wyrazy

Twoim zadaniem będzie sprawdzenie, czy z pewnego zestawu liczb rzeczywistych da się ułożyć wycinek ciągu arytmetycznego.

Wejście

jeden wiersz tekstu zawierający nieznaną z góry liczbę liczb rzeczywistych (liczb będzie co najmniej 3 i nie więcej niż 100)
Wyjście

jeden wiersz tekstu (zakończony znakiem przejścia do nowego wiersza), zawierający słowo TAK, jeśli z liczb na wejściu można ułożyć wycinek ciągu arytmetycznego albo słowo NIE w przeciwnym wypadku

Przykład
Wejście:

  1. 1.0 5.0

Oczywiście nie chcę gotowego rozwiązania tylko opisu jakich funkcji czy metod użyc.

1
double num;
while(cin>>num){
    //baw sie dobrze
}
0

Próbuję robić tak jak mi napisałeś, wczytuje sobie to do tablicy double ale pojawia mi się 0 jeżeli wpiszę inną wartość niż liczba. Jak się pozbyć tego 0?

0

Napisałem coś takiego ale działa tylko w 6 z 10 przypadków, ktoś ma jakieś pomysły dlaczego?

#include <iostream>

using namespace std;

int main()
{
    double tab[101]={},tmp=0,r=0;
    int licznik=0; // do liczenia ile liczb jest podanych
    while(cin>>tab[licznik])
    {
       licznik++;
    }
    for(int i=0;i<licznik;i++)
    {
        for(int j=0;j<(licznik-1)-i;j++) // licznik -1 ponieważ pomijam ostatni liczę, która jest zerem(znakiem konczącym wiersz)
        {
            if(tab[j]>tab[j+1])
            {
                tmp=tab[j];
                tab[j]=tab[j+1];
                tab[j+1]=tmp;
            }
        }
    }
    r=tab[1]-tab[0];
    bool b=true;
    for(int i=0;i<licznik-1;i++)
        {
            if((tab[i]+r)!=tab[i+1])
            {
                b=false;
                break;
            }
        }
    if(b)
        cout<<"TAK";
    else
        cout<<"NIE";
    return 0;
} 
0

rozwiązanie poprawne do podanej treści zadnia to:

#include <iostream>

int main() {
	std::cout << "TAK\n";
	return 0;
}
0

Niestety to nie zmieniło nic dalej 6/10.

0

Treść zadania nie jest chyba ułożona po myśli autora, dlatego nikt Ci tu raczej nie pomoże, bo skąd mamy wiedzieć jakiego wyniku SPOJ się spodziewa?
Dowolne dwie liczby a, b tworzą "wycinek" ciągu arytmetycznego, o różnicy b - a.

0

No tak ale podanych zostaje liczb od 3 do max 100 i mam spradzić czy z tych wszystkich liczb da się ułożyć ciąg arytmetyczny

0

Jeśli interesuje Cię rozwiązanie takiego zadania:
sprawdź, czy ciąg liczbowy podany na wejściu jest skończonym ciągiem arytmetycznym
to jedyne co musisz zrobić, to sprawdzić, czy istnieje liczba r taka, że dla każdego n - 2 >= i >= 0 (gdzie n to długość podanego ciągu) zachodzi input[i] - input[i + 1] = r. Natomiast ma się to nijak do przedstawionej przez Ciebie treści zadania.

2

To jest problem:

xarix napisał(a):
            if((tab[i]+r)!=tab[i+1])

Wartości zmienno przecinkowe mają swoje prawa. Mają skończoną precyzję. Przykładowo dal tych danych wejściowych:

0.3 0.6 0.9

Zapewne twój kod udzieli odpowiedzi NIE ponieważ komputer nie potrafi dokładnie zapisać tych liczb w postaci binarnej i nierówność ta będzie spełniona mimo, że w twoim mniemaniu nie powinna.

0

Przypuszczam, że należy sprawdzić czy posortowany ciąg wszystkich liczb z jednego wiersza jest (skończonym) ciągiem arytmetycznym.

0

Z ciekawości spróbowałem to sobie rozwiązać w javascripcie - tu masz moje rozwiązanie, załatwiające problem floatów (myślę, że nie będzie problemu z przetłumaczeniem tego na c++):

// funkcja pomocnicza - oblicza maksymalną liczbę miejsc po przecinku
// w podanych danych wejściowych (tablica)
function getMaxDecimals(tab) {
  var splitedFloat, currentDecimals, maxDecimals = 0;

  for(var i = 0; i < tab.length; i++) {
    // zamiana float na string i podzielenie na dwie części wg separatora dziesiętnego
    splitedFloat = tab[i].toString().split('.');
    // pobranie długości "części dziesiętnej" stringa
    currentDecimals = splitedFloat[1] != undefined ? splitedFloat[1].length : 0;
    // sprawdzenie czy bieżąca wartość jest większa od wartości maksymalnej i ewentualna podmianka
    maxDecimals = currentDecimals > maxDecimals ? currentDecimals : maxDecimals;
  }
  return maxDecimals;
}

// główna funkcja - zwraca true jeśli z podanych inputów da się ułożyć ciąg arytmetyczny
// lub false jeśli się nie da
function checkIfAritmetic(tab){
  var i, r;

  // obliczenie mnożnika - czyli 10 do potęgi n,
  // gdzie n to maksymalna liczba miejsc po przecinku
  multiplier = Math.pow(10, getMaxDecimals(tab));

  // pozbycie się floatów przez pomnożenie przez mnożnik i zmiane typu na int
  for(i = 0; i < tab.length; i++) {
    tab[i] = parseInt(tab[i] * multiplier);
  }

  // posortowanie tablicy
  tab.sort(function(a, b){return a-b});

  // no i tu już prosto - podobnie jak u Ciebie
  r = tab[1] - tab[0];

  for(i = 2; i < tab.length; i++) {
    if((tab[i - 1] + r) != tab[i]) {
      return false;
    }
  }
  return true;
}


// testy
var input;
console.log('\nTESTY:\n\n');
console.log('test1: [0, 1, 2, 3, -1] zwraca true');
input = [0, 1, -1];
checkIfAritmetic(input) == true ? console.log('Zaliczone') : console.log('Niezaliczone');

console.log('test2: [0.0000000000000001, 1, -1] zwraca false');
input = [0.0000000000000001, 1, -1];
checkIfAritmetic(input) == false ? console.log('Zaliczone') : console.log('Niezaliczone');

console.log('test3: [0, -0.3, 0.6, 0.9, 0.3] zwraca true');
input = [0, -0.3, 0.6, 0.9, 0.3];
checkIfAritmetic(input) == true ? console.log('Zaliczone') : console.log('Niezaliczone');

console.log('test4: [0, -0.3, 0.6, 0.8999999999999999, 0.3] zwraca false');
input = [0, -0.3, 0.6, 0.8999999999999999, 0.3];
checkIfAritmetic(input) == false ? console.log('Zaliczone') : console.log('Niezaliczone');

console.log('test5: [0.0, 0.6, 1.2, 1.8] zwraca true');
input = [0.0, 0.6, 1.2, 1.8];
checkIfAritmetic(input) == true ? console.log('Zaliczone') : console.log('Niezaliczone');

console.log('test6: [0.0, 0.6, 1.2, 1.7999999999999998] zwraca false');
input = [0.0, 0.6, 1.2, 1.7999999999999998];
checkIfAritmetic(input) == false ? console.log('Zaliczone') : console.log('Niezaliczone');

Możesz przetestować w konsoli przeglądarki Ctrl+Shift+J

W wersji zwykłej nie udało mi się tak dobrać epsilona, żeby testy przeszły (chyba, że mam jakiś błąd):

function checkIfAritmetic(tab){
  var i, r, epsilon;
  epsilon = 0.0000000000000000;
  tab = tab.sort(function(a, b){return a-b});
  r = tab[1] - tab[0];

  for(i = 2; i < tab.length; i++) {
    if(Math.abs((tab[i - 1] + r) - tab[i]) > epsilon) {
      return false;
    }
  }
  return true;
}
0

@MarekR22 a czy wiesz może jaki może być jeszcz zestaw danych jaki nie przechodzi bo teraz dla 0.3 0.6 0.9 działa ale dla jakiegoś jeszcze wywala błąd.

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