Wyklepałem nowy znajdowacz kątów o ogromnej precyzji:
#include <cmath>
#include <cfloat>
#include <limits>
#include <iostream>
#include <algorithm>
using namespace std;
#define __TAK__ { cout /*<< __LINE__*/ << "TAK\n"; return 0; }
#define __NIE__ { cout /*<< __LINE__*/ << "NIE\n"; return 0; }
#define __EPS__ { cout /*<< __LINE__*/ << "EPS\n"; return 1; }
int main()
{
int a, b, c, d;
long double _c, _d, alfa, beta;
cin >> a >> b >> c >> d;
if (a < b) swap(a, b); // a >= b
if (c < d) swap(c, d); // c >= d
if ( d > b ) __NIE__ // thickness
if ( a >= c ) __TAK__ // fit check
if ( c == d ) __NIE__ // square cXd
alfa = atan2(b, a); // y, x
beta = atan2(d, c); // y, x
_c = c * cos(alfa) + d * sin(alfa);
_d = c * sin(alfa) + d * cos(alfa);
if ( a > _c && b > _d ) __TAK__
if ( a <= _c && b <= _d ) __NIE__
if ( beta > alfa ) __NIE__
int step = 1;
bool cross = false;
long double eps = LDBL_EPSILON;
long double lower = abs( alfa - beta );
long double upper = alfa;
enum{ EPS, TAK, NIE } answer;
do{
if (a < _c && b < _d) { answer = NIE; break; }
if (a > _c && b > _d) { answer = TAK; break; }
if (beta < eps) { answer = EPS; break; }
_c > a ? lower = alfa : upper = alfa;
if ( cross != (_c > a) ) beta = (upper - lower) / 2;
( cross = _c > a ) ? alfa += beta : alfa -= beta;
_c = c * cos(alfa) + d * sin(alfa);
_d = c * sin(alfa) + d * cos(alfa);
} while ( step++ );
switch( answer )
{
case NIE: cout << "NIE"; break;
case TAK: cout << "TAK"; break;
case EPS: cout << "EPS"; break;
}
cout.precision(16);
cout << '\t'<< step << '\t' << alfa << '\t' << beta << '\n';
cout << _c << '\t' << _d << '\t' << (a - _c) << '\t' << (b - _d) << '\n';
if( answer == EPS && (!((a - _c) + (b - _d)) || !(a - _c) || !(b - _d) ) )
cout << "Warning!\t ---- Oscillation! ---- \n";
}
Wygląda na to, że autor zadania pomylił się w treści lub testach,
mówiąc że ma się zmieścić “nie dotykając jego krawędzi”…
Przedstawione w testach przypadki są wpisywalne…
Te testy według mnie powinny zwracać wyłącznie NIE:
6
56 70 10 80
73 88 95 20
82 65 10 95
91 77 95 25
151 122 170 25
171 200 205 60
Wygląda na to że te przypadki generują takie coś:
56 70 10 80
EPS 95 0.6435011087932844 5.421010862427522e-20
70 56 0 3.469446951953614e-18
Warning! ---- Oscillation! ----
73 88 95 20
EPS 94 0.6435011087932844 8.131516293641283e-20
88 73 -6.938893903907228e-18 6.938893903907228e-18
Warning! ---- Oscillation! ----
82 65 10 95
EPS 96 0.6435011087932844 5.421010862427522e-20
82 65 0 0
Warning! ---- Oscillation! ----
91 77 95 25
EPS 101 0.6435011087932844 5.421010862427522e-20
91 77 0 0
Warning! ---- Oscillation! ----
151 122 170 25
EPS 93 0.6435011087932844 5.421010862427522e-20
151 122 0 6.938893903907228e-18
Warning! ---- Oscillation! ----
171 200 205 60
EPS 99 0.6435011087932844 5.421010862427522e-20
200 171 -2.775557561562891e-17 2.775557561562891e-17
Warning! ---- Oscillation! ----
Próby dopasowania nie dość że rozbijają się o epsilon,
to i jeszcze c′ i d′ są praktycznie równe bokom a i b…
Co ciekawsze, ich częścią wspólną jest kąt ~36.87°.
Proszę, wyprowadźcie mnie z możliwego błędu. 