Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 20.03.2015, 16:04   #1
Ilya_S
Новичок
Джуниор
 
Регистрация: 20.03.2015
Сообщений: 1
По умолчанию Задача с Timus (C++), не проходит тест 20

Здравствуйте!

Очень заинтересовала задача на тимусе.

Вроде как решение получено и все несколько раз перепроверил и на ручных тестах все работает, но полностью проверку не проходит. Что я упущено в решении?

Код:
#include <cstdio>
#include <cmath>
#include <vector>

using namespace std;

class Point
{
	public:
		Point(double x = 0, double y = 0, double z = 0): X(x), Y(y), Z(z) {};
		Point(const Point& p): X(p.X), Y(p.Y), Z(p.Z) {};
		Point operator-(const Point& b){ return Point(X-b.X, Y-b.Y, Z-b.Z);}
		Point operator+(const Point& b){ return Point(X+b.X, Y+b.Y, Z+b.Z);}

		Point& Normalize()
 		{
			double length = GetLength();
			X /= length;
			Y /= length;
			Z /= length;
			return *this;
  		}
		
		static double ScalarMultyVector(Point a, Point b) 
		{
			return a.X*b.X + a.Y*b.Y + a.Z*b.Z;
		};
		static Point MultyVector(Point p1, Point p2)
		{
			return Point(
				p1.Y*p2.Z - p1.Z*p2.Y,
				-(p1.X*p2.Z - p1.Z*p2.X),
				p1.X*p2.Y - p1.Y*p2.X
			);
		}
		Point MultyScalar(double scalar){ return Point(X*scalar, Y*scalar, Z*scalar); } 
		double GetLength(){ return sqrt(X*X + Y*Y + Z*Z);} 
		double GetQrtLength(){ return X*X + Y*Y + Z*Z;}
		
		double X;
		double Y;
		double Z;
}; 

class Plane
{
	public:
		Plane(Point p1, Point p2, Point p3)
		{
			Point v1(p2 - p1);
			Point v2(p3 - p1);
			Point n( Point::MultyVector(v1, v2) );
			
			A = n.X;
			B = n.Y;
			C = n.Z;
			D = -p1.X*n.X - p1.Y*n.Y - p1.Z*n.Z;
		}
		
		double GetDistance(Point a)
		{
			return abs(A*a.X + B*a.Y + C*a.Z + D)/GetNormal().GetLength();
		}

		Point GetNormal()
		{
			return Point(A, B, C);
		}

		double A;
		double B;
		double C;
		double D;
};

bool IsPointInSphere(Point p)
{
	return p.X*p.X + p.Y*p.Y + p.Z*p.Z <= 100*100;
}

void SortPoint(Point p, vector<Point>& in, vector<Point>& out)
{
	if( IsPointInSphere(p) )
		in.push_back(p);
	else
		out.push_back(p);
}

double GetTriangleSquare(Point p1, Point p2, Point p3)
{
	Point v1(p2 - p1);
	Point v2(p3 - p1);
	return abs( Point::MultyVector(v1, v2).GetLength() / 2 );
}  

Point GetPointOnSphere(Point in, Point out)
{
	Point v(out - in);
	double a = v.GetQrtLength();
	double b = Point::ScalarMultyVector(in, v);
	double c = in.GetQrtLength();
	double t = (-b + sqrt(b*b - a*c) ) / a;
	
	return in + v.MultyScalar(t);
}

double GetSectorSquare(Point center, Point p1, Point p2)
{
	Point v1(p1 - center);
	Point v2(p2 - center);
	double angle = acos( Point::ScalarMultyVector(v1, v2) / (v1.GetLength() * v2.GetLength() ) );
	return v1.GetLength() * angle;
}

double GetSquare(Point p1, Point p2, Point p3)
{
	Plane plane(p1, p2, p3);	
	double distance = plane.GetDistance(Point(0, 0, 0));
	
	if(distance >= 100)
		return 0.0;
	
	Point center( plane.GetNormal().Normalize().MultyScalar(distance) );
	
	vector<Point> in, out;
	SortPoint(p1, in, out);	
	SortPoint(p2, in, out);	
	SortPoint(p3, in, out);	

	switch(in.size())
	{
		case 3:
			return GetTriangleSquare(p1, p2, p3);
		case 2:
		{
			Point p4( GetPointOnSphere(in[0], out[0]) );
			Point p5( GetPointOnSphere(in[1], out[0]) );
			return GetTriangleSquare(in[0], in[1], p4) + GetTriangleSquare(p4, p5, in[1]) + 
					GetSectorSquare(center, p4, p5) - GetTriangleSquare(center, p4, p5);
		}
		case 1:
		{
			Point p4( GetPointOnSphere(in[0], out[0]) );
			Point p5( GetPointOnSphere(in[0], out[1]) );
			return GetTriangleSquare(in[0], p4, p5) +
					GetSectorSquare(center, p4, p5) - GetTriangleSquare(center, p4, p5);
		}
	}

	return 0.0;
}

int main(int argc, char *argv[])
{
	Point p1, p2, p3;
	scanf("%lf%lf%lf", &p1.X, &p1.Y, &p1.Z);
	scanf("%lf%lf%lf", &p2.X, &p2.Y, &p2.Z);
	scanf("%lf%lf%lf", &p3.X, &p3.Y, &p3.Z);
	
	printf("%lf", GetSquare(p1, p2, p3));
	return 0;
}
Ilya_S вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
неубывающую последовательность чисел максимальной длины. Не проходит 11 тест (TurboPascal) VladKB1 Помощь студентам 9 14.06.2014 23:06
не могу пройти тест на timus nowhow Помощь студентам 1 02.04.2014 23:59
Задача из школьной олимпиады.Решение не проходит один из тестов. Че Гевара Общие вопросы C/C++ 2 03.10.2013 14:17