SPOJ nie akceptuje odpowiedzi

0

Witam, już od paru dni męczę się z pewnym zadaniem, i nie mogę wychwycić gdzie mam błąd, ponieważ program typu SPOJ nie chce mi go zaakceptować, dlatego zwracam się tu o pomoc, z góry dziękuje ! :)

Robot porusza się na płaszczyźnie wzdłuż łamanej złożonej z odcinków. Obecnie przemieszcza się z punktu A0 do punktu A1. Następnie odwiedzi punkty A2, A3, ..., An. Oblicz, w którą stronę robot powinien skręcać oraz wartość cosinusa kąta skrętu dla każdego z punktów A1, A2, ..., An-1.
Wejście

W pierwszej linii jedna liczba 2<=n<=1000, a w kolejnych n+1 liniach po dwie liczby całkowite:
xi yi
z przedziału [-1000..1000] będące współrzędnymi kolejnych punktów marszruty robota.

Można założyć, że kolejne punkty są różne.
Wyjście

W kolejnych n-1 liniach najpierw litera L dla skrętu w lewo (R dla skrętu w prawo), odstęp, a następnie cosinus kąta skrętu z dokładnością do 6 miejsc dziesiętnych po kropce. Jeśli w danym punkcie robot pownien poruszać się prosto należy wydrukować tylko literę F, a jeśli do tyłu, to literę B.
Przykład

Wejście:
5
0 0
1 0
2 0
-2 0
-2 -2
0 4

Wyjście:
F
B
L 0.000000
L -0.948683

A tu mój kod:

#include <iostream>
#include <cmath>
int main()
{
    std::cout.precision(6);
    std::cout.setf(std::ios::fixed);
    int n;
    std::cin >> n;
    int tabx[n + 1], taby[n + 1];

    for (int j = 0; j <= n; j++) // wprowadzanie danych
    {
        std::cin >> tabx[j];
        std::cin >> taby[j];
    }

    for (int i = 1; i < n; i++) {

        long int ax, ay, bx, by, w, w1;
        ax = tabx[i] - tabx[i - 1];
        ay = taby[i] - taby[i - 1]; // wektor pierwszy
        bx = tabx[i + 1] - tabx[i];
        by = taby[i + 1] - taby[i]; // wektor drugi
        //obliczanie wyznacznika ruchu
        w = (ax * by) - (ay * bx);
        //obliczanie cosinusa
        w1 = (ax * bx) + (ay * by);

        long double w2 = sqrt(ax * ax + ay * ay),
                    w3 = sqrt(bx * bx + by * by);

        long double kat = (double)w1 / (w2 * w3);

        if (w == 0) // gdy sa rownoglegle
        {
            if (kat == 1) // gdy cosinus rowna sie 0 stopni
                std::cout << "F" << std::endl;
            else if (kat == -1) // gdy rowna sie 180 stopni
                std::cout << "B" << std::endl;
        }

        else {
            if (w > 0) //skret w lewo

                std::cout << "L " << kat << std::endl;

            else // skret w prawo

                std::cout << "P " << kat << std::endl;
        }
    }

    return 0;
}
0

Porównujesz liczby zmiennopozycyjne przez == zamiast z epsilonem, ponadto kat rzutujesz na double'a i może dzielisz przez zero.

0

Najprostsze dane testowe:

3
0 0 
16 16
999 999

dają nieprawidłowy wynik:
http://ideone.com/4LGVVS
od kiedy to cosinus kąta rzeczywistego ma wartość mniejszą od -1 ?

0

Hmm, dzięki za odpowiedź, zrobiłem następująco, wykluczyłem to dzielenie przez 0 i już na pewno nie będzie miało miejsca oraz wprowadziłem porównanie przez epsilon, po zapoznaniu się z tym(szczerze to o tym nie wiedziałem ;)) i hmm dalej nie działa, więc sam już nie wiem co można by jeszcze zrobić, chyba że epslion został źle zastosowany.

#include <iostream>
#include<cmath>
int main ()
{
std::cout.precision(6);
std::cout.setf(std::ios::fixed);
int n;
std::cin>>n;
int tabx[n+1],taby[n+1];

const double EPS = 0.000001;
for(int j = 0 ; j <= n ; j ++) // wprowadzanie danych
{
std::cin>>tabx[j];
std::cin>>taby[j];
}
for( int i = 1; i<n ; i++)
{
long int ax,ay,bx,by,w,w1;
ax = tabx[i]-tabx[i-1]; ay = taby[i]-taby[i-1]; // wektor pierwszy
bx = tabx[i+1]-tabx[i]; by = taby[i+1]-taby[i]; // wektor drugi
//obliczanie wyznacznika ruchu
w = (axby)-(aybx);
//obliczanie cosinusa
w1 = (axbx)+(ayby);

	long double w2 = sqrt(ax*ax+ay*ay),
				w3 = sqrt(bx*bx+by*by),
				w4 = w2*w3;
				if(w2==0 || w3==0)
				{
					if(w>0)//skret w lewo
							std::cout<< "L 0.000000"<<std::endl;	
					else  // skret w prawo
						std::cout<< "P 0.000000"<<std::endl;
				}
				else
				{
				
				long double kat = (double) w1/w4; 
				
					if(w == 0) // gdy sa rownoglegle
					{	
						if ( fabs(1-kat) >EPS ) // gdy cosinus rowna sie 0 stopni
							std::cout<< "B" << std::endl;
						else if (fabs (-1 - kat) > EPS) // gdy rowna sie 180 stopni
							std::cout<< "F" << std::endl;
					}
					else
					{
						if(w>0)//skret w lewo
							std::cout<< "L "<<kat<<std::endl;		
						else  // skret w prawo
							std::cout<< "P "<<kat<<std::endl;
					}
	
				}
}


return 0;

}

0

Dalej masz skopane porównywanie z epsilonem, porównujesz nie w tę stronę, co trzeba. Używaj debuggera, jak już masz nieprzechodzący test, to podejrzyj wszystkie wartości.

Poza tym cosinus nie równa się 0 stopni, cosinus daje liczbę rzeczywistą.

0

Szybka poprawka i działa już lepiej: https://ideone.com/QTbVAA

0
MarekR22 napisał(a):

Najprostsze dane testowe:

3
0 0 
16 16
999 999

dają nieprawidłowy wynik:
http://ideone.com/4LGVVS
od kiedy to cosinus kąta rzeczywistego ma wartość mniejszą od -1 ?

Co do złego wyniku to faktycznie, tyle razy już coś zmieniałem w tym programie że przestał działać, chyba od początku muszę go napisać, dziękuje wszystkim za pomoc ;) ( skorzystam z nowych wskazówek ).

P.S. Z tego co widzę to nigdy nie sprawdzam czy cosinus ma wartość mniejszą niż -1 tylko czy jest równy -1, a taka sytuacja może zaistnieć.

0
Dizde napisał(a):

P.S. Z tego co widzę to nigdy nie sprawdzam czy cosinus ma wartość mniejszą niż -1 tylko czy jest równy -1, a taka sytuacja może zaistnieć.

Ty to na serio napisałeś?

Generalnie masz dwa, błędy.
Dynamiczny rozmiar tablicy, który jak widać nie działa (patrz linki od ideone).
Jak słusznie napisał @Afish wpisałem niezgodne z treścią zadania dane, a twój program potraktował je tak jak oczekiwałem, ergo masz też błąd związany z tym.
Weź użyj debuggera i prześledź krok po kroku jak działa twój program (nie chodzi o to, by dać ci gotowe rozwiązanie, ale żebyś się czegoś nauczył(a)).

0

Szczerze mówiąc to korzystałem z tej strony http://www.naukowiec.org/przelicznik-katow.html , i tam po wpisaniu wartości -1 pokazuje 180 stopni dla 1 pokazuje 0 a dla 0 pokazuje 90.
Nie sprawdzałem tego dokładnie,a moja wiedza no cóż jest dość skromna na ten temat ;)

0

Najważniejsza zmiana to chyba wyświetlanie R zamiast P, bo SPOJ trzyma się zasad. Użyj tablicy dynamicznej, jak panowie wyżej wspomnieli i użyj porównania z epsilonem. Powinno przejść ;)

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