Народ,помогите пожалуйста кто чем сможет,горю на сессии,надо срочно решить задачу в паскале с сайта olympiads.ru. Там даны условия(позже напишу) и есть решения в С++ и объяснения,а надо решить в Pascal ABC. Сможет кто нить здесь помочь? Вот условие Задача E. Стройка-2
Имя входного файла: e.in Имя выходного файла: e.out Максимальное время работы на одном тесте: 1 секунда Максимальный объем используемой памяти: 64 мегабайта На территории строительства растут два дерева. Согласно плану работ, оба дерева попадают внутрь будущей цветочной клумбы, имеющей форму круга. Нужно огородить эти деревья треугольным забором так, чтобы ограждение содержалось внутри будущей клумбы.
Деревья на плане изображаются кругами, которые могут пересекаться друг с другом или даже быть вложены один в другой (деревья могли срастись из-за локальных загрязнений окружающей среды, неизбежных при строительстве). Они лежат внутри окружности, соответствующей клумбе, но могут касаться её.
Напишите программу, которая по введенной информации о клумбе и деревьях определит, возможно ли построить треугольный забор, не выходящий за пределы клумбы (при этом его вершины могут лежать на границе клумбы) и содержащий оба дерева внутри (касание забора и деревьев также разрешается).
Формат входных данных
Вводится информация о трех окружностях: каждая задается координатами центра и радиусом. Все числа целые, не превосходящие по модулю 1000, радиус - натуральное число. Клумбе соответствует первая окружность, вторая и третья окружности лежат внутри первой и соответствуют деревьям.
Формат выходных данных
Если деревья невозможно оградить забором, не выходящим за границы клумбы, выведите impossible. Иначе в первую строку запишите possible, а в следующие - координаты вершин искомого треугольника. Если ответов несколько, выведите любой.
Примеры
e.in 0 0 1000 0 0 500 0 0 500
e.out possible -468.09507906626652000000 -883.67810709213904000000 -531.24014997680422000000 847.22128340394170000000 999.33522904307131000000 36.45682368819722500000 Решение в С++
L getLine(P p1, P p2) { // дано: две несовпадающих точки p1 и p2. возвращает прямую, их содержащую D x0=p1.x, y0=p1.y; D al=(p2-p1).x, be=(p2-p1).y; return L(be,-al,al*y0-be*x0); }
P getPoint(L l1, L l2) { // дано: две прямые l1 и l2, которые пересекаются. возвращает точку пересечения D det=l1.a*l2.b-l1.b*l2.a; D det1=-(l1.c*l2.b-l1.b*l2.c); D det2=-(l1.a*l2.c-l1.c*l2.a); return P(det1/det,det2/det); }
struct C { // окружность с центром в точке о и радиусом r P o; D r; C() {} C(P o, D r): o(o), r® {} bool contains(C c) { D d=(c.o-o).len(); return d+c.r<r+eps; } void load() { o.load(); cin>>r; } };
vector<P> crossCircleAndLine(C c, L l) { vector<P> res; // результат D al,be; // направляющий вектор прямой l al=l.b; be=-l.a; D x0,y0; // точка на прямой l if (abs(l.a)<abs(l.b)) { x0=0; y0=-l.c/l.b; } else { y0=0; x0=-l.c/l.a; } // теперь x=x0+al*t, y=y0+be*t, подставляем в уравнение окружности и решаем квадратное уравнение a*t^2+b*t+c=0; D A,B,C,t; A=sqr(al)+sqr(be); B=2*al*(x0-c.o.x)+2*be*(y0-c.o.y); C=sqr(x0-c.o.x)+sqr(y0-c.o.y)-sqr(c.r); D d=B*B-4*A*C; // дискриминант if (d<-eps) return res; // решений нет if (d<0) d=0; // чтобы не было RE при d чуть меньшем нуля t=(-B+sqrt(d))/(2*A); // одно решение res.push_back(P(x0+al*t,y0+be*t)); t=(-B-sqrt(d))/(2*A); // второе решение res.push_back(P(x0+al*t,y0+be*t)); return res; }
vector<P> crossTwoCircles(C c1, C c2) { // вычев из одного уравнения окружности другое, получим уравнение прямой ax+by+c=0 D a,b,c; a=2*(c2.o.x-c1.o.x); b=2*(c2.o.y-c1.o.y); c=sqr(c2.r)-sqr(c1.r)+sqr(c1.o.x)-sqr(c2.o.x)+sqr(c1.o.y)-sqr(c2.o.y); return crossCircleAndLine(c1,L(a,b,c)); }
int sgn(D x) { // знак числа х if (x>eps) return 1; if (x<-eps) return -1; return 0; }
struct Circles2Solver { C c1,c2,c3; int buben; Circles2Solver(int buben): buben(buben) {} P getPoint(D x) { return c1.o+P(c1.r,0).rotate(x); } vector<P> getSide(D x) { P p=getPoint(x); vector<P> to; C circles[2]; circles[0]=c2, circles[1]=c3; for (int t=0; t<2; t++) { C c=circles[t]; D d=(p-c.o).len(); D l=sqrt(max(0.,sqr(d)-sqr(c.r))); if (l<eps) continue; vector<P> add=crossTwoCircles(C(p,l),c); for (int i=0; i<sz(add); i++) to.pb(add[i]); } if (sz(to)==0) return vector<P>(); int l=0,r=0; for (int i=0; i<sz(to); i++) { if ((to[i]-p)*(to[l]-p)<-eps) l=i; if ((to[i]-p)*(to[r]-p)>eps) r=i; } assert(l!=r); vector<P> tmp; tmp=crossCircleAndLine(c1,getLine(p,to[l])); assert(sz(tmp)==2); P p1=tmp[0]+tmp[1]-p; tmp=crossCircleAndLine(c1,getLine(p,to[r])); if (sz(tmp)!=2) { p.save(); to[r].save(); } assert(sz(tmp)==2); P p2=tmp[0]+tmp[1]-p; vector<P> res; res.pb(p1); res.pb(p2); return res; } D getValue(D x) { P p=getPoint(x); vector<P> tmp=getSide(x); if (sz(tmp)!=2) return -1e100; P p1=tmp[0]; P p2=tmp[1]; L line=getLine(p1,p2).norm(); double res=1e100; C circles[2]; circles[0]=c2, circles[1]=c3; for (int t=0; t<2; t++) { C c=circles[t]; D cur; D d=abs(line.getValue(c.o)); if (sgn(line.getValue(c.o))==sgn(line.getValue(p))) cur=d; else cur=-d; cur-=c.r; res=min(res,cur); } return res; } void findMinValue(D l, D r, D &x, D &minVal) { for (int step=0; step<50; step++) { D len=r-l; D m1=l+len/3; D m2=r-len/3; D v1=getValue(m1); D v2=getValue(m2); if (v1<v2) l=m1; else r=m2; x=r; minVal=getValue(x); } } vector<P> getValidTriangle(C _c1, C _c2, C _c3) { c1=_c1, c2=_c2, c3=_c3; assert(c1.contains(c2) && c1.contains(c3)); for (int i=0; i<buben-1; i++) { D l=2*pi/buben*i; D r=2*pi/buben*(i+1); D x,minVal; findMinValue(l,r,x,minVal); if (minVal>-eps) { cerr<<minVal<<endl; vector<P> res=getSide(x); res.pb(getPoint(x)); if (!checkTriangle(res)) cout<<"botva\n"; return res; } } return vector<P>(); } bool checkTriangle(vector<P> p) { double eps=1e-5; assert(sz(p)==3); for (int i=0; i<3; i++) { cerr<<(c1.o-p[i]).len()<<endl; if ((c1.o-p[i]).len()>c1.r+eps) return false; } double area=0; for (int i=0; i<3; i++) area+=p[i]*p[(i+1)%3]; area=abs(area); C circles[2]; circles[0]=c2, circles[1]=c3; for (int t=0; t<2; t++) { C c=circles[t]; double area2=0; for (int i=0; i<3; i++) area2+=abs((p[i]-c.o)*(p[(i+1)%3]-c.o)); if (abs(area-area2)>eps) return false; } for (int t=0; t<2; t++) { C c=circles[t]; for (int i=0; i<3; i++) { L line=getLine(p[i],p[(i+1)%3]).norm(); if (abs(line.getValue(c.o))<c.r-eps) return false; } } return true; } };
int main() { freopen("e.in","r",stdin); freopen("e.out","w",stdout);
C c1,c2,c3; c1.load(); c2.load(); c3.load(); Circles2Solver solver(113); vector<P> triangle=solver.getValidTriangle(c1,c2,c3); if (sz(triangle)==0) cout<<"impossible\n"; else { cout<<"possible\n"; for (int i=0; i<3; i++) triangle[i].save(); }