Оптимизация кода - C (СИ)

Узнай цену своей работы

Формулировка задачи:

Нужно оптимизировать код, т.к. при сдаче работы есть ограничение по времени - 1с, а к сожалению работа занимает дольше 1 секунды.Подозреваю что работает долго из-за цикла в цикле в цикле. Помогите оптимизировать пожалуйста P.S. Прога полностю верная, проверено стресс-тестом
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
 
double
S(double x1, double y1, double x2, double y2, double x3, double y3)
{
    double a,b,c,p;
    a=sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));
    b=sqrt((x3-x2)*(x3-x2)+(y3-y2)*(y3-y2));
    c=sqrt((x3-x1)*(x3-x1)+(y3-y1)*(y3-y1));
    p=(a+b+c)/2;
    return (p*(p-a)*(p-b)*(p-c));
}
int
main(void)
{
int n,i,j,k,m,x,y;
    double max_S,tmp;
    scanf("%d", &n);
    double Xc[n];
    double Yc[n];
    for (i=0; i<=n-1; i++) {
        scanf("%d%d", &x, &y);
        Xc[i]=x;
        Yc[i]=y;
    }
    max_S=0;
    for (j=0;j<=n-3; j++){
        for (k=j+1;k<=n-2; k++) {
            for (m=k+1;m<=n-1; m++){
                tmp=S(Xc[j],Yc[j],Xc[k],Yc[k],Xc[m],Yc[m]);
                if (tmp>max_S){
                    max_S=tmp;
                }
            }
        }
    }
    printf("%.6lf", sqrt(max_S));
    return 0;
}
Собственно, вот задача На плоскости задан набор точек. Определите площадь наибольшего из треугольников, которые можно построить, используя тройки заданных точек в качестве вершин. На стандартном потоке ввода задаётся сначала натуральное число N (1 ≤ N ≤ 650), а затем — координаты N точек в виде Xi, Yi. Координаты каждой точки задаются на отдельной строке и разделены пробелом. Все координаты — целые числа, не превосходящие по модулю 100. Точки в наборе могут повторяться. На стандартный поток необходимо напечатать единственное число — площадь наибольшего из треугольников, образованных тройками из данного набора точек. Выводите ответ с шестью знаками после десятичной точки.
Люди, помогите =(

Решение задачи: «Оптимизация кода»

textual
Листинг программы
/////////////////////////////////////////////////////////////////////////////////////
//Нужно оптимизировать код, т.к. при сдаче работы есть ограничение по времени - 1с, 
//а к сожалению работа занимает дольше 1 секунды.
//
//Собственно, вот задача
//На плоскости задан набор точек. Определите площадь наибольшего из треугольников, 
//которые можно построить, используя тройки заданных точек в качестве вершин.
//На стандартном потоке ввода задаётся сначала натуральное число N (1 ≤ N ≤ 650), 
//а затем — координаты N точек в виде Xi, Yi. Координаты каждой точки задаются 
//на отдельной строке и разделены пробелом. Все координаты — целые числа, 
//не превосходящие по модулю 100. Точки в наборе могут повторяться.
//На стандартный поток необходимо напечатать единственное число — площадь наибольшего 
//из треугольников, образованных тройками из данного набора точек. 
//Выводите ответ с шестью знаками после десятичной точки.
/////////////////////////////////////////////////////////////////////////////////////
#include <algorithm>
#include <complex>
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <iterator>
#include <limits>
#include <set>
#include <vector>
/////////////////////////////////////////////////////////////////////////////////////
typedef double                 T_coord;
typedef std::complex<T_coord>  T_point;
typedef std::vector<T_point>   T_points;
/////////////////////////////////////////////////////////////////////////////////////
template<class T>
bool  equal_to_for_real(T a, T b) 
{
    const T  coef = 10;
    return abs(a - b) < std::numeric_limits<T>::epsilon() * coef;
}
/////////////////////////////////////////////////////////////////////////////////////
template<class T>
bool  greater_for_real(T a, T b) 
{
    return a > b
           && !equal_to_for_real(a, b);
}
/////////////////////////////////////////////////////////////////////////////////////
template<class T>
bool  less_for_real(T a, T b) 
{
    return a < b
           && !equal_to_for_real(a, b);
}
/////////////////////////////////////////////////////////////////////////////////////
template<class T>
bool  greater_equal_for_real(T a, T b) 
{
    return !less_for_real(a, b);
}
/////////////////////////////////////////////////////////////////////////////////////
template<class T>
bool  less_equal_for_real(T a, T b) 
{
    return !greater_for_real(a, b);
}
/////////////////////////////////////////////////////////////////////////////////////
struct T_point_generator
{
    int mod_;
    //-------------------------------------------------------------------------------
    T_point_generator(int mod) : mod_(mod)
    {}
    //-------------------------------------------------------------------------------
    T_point  operator() ()
    {
        T_coord  X = rand() % mod_;
        T_coord  Y = rand() % mod_;
        return  T_point(X, Y);    
    }
};
/////////////////////////////////////////////////////////////////////////////////////
void  get_points(T_points&  points)
{
    const int MOD = 100;
    std::generate(points.begin(), points.end(), T_point_generator(MOD));
}
/////////////////////////////////////////////////////////////////////////////////////
struct  T_bottom_left_compare
{
    bool operator() (T_point A, T_point B)
    {
        return equal_to_for_real(A.imag(), B.imag()) 
            ? less_for_real(A.real(), B.real()) : less_for_real(A.imag(), B.imag());
    }
};
/////////////////////////////////////////////////////////////////////////////////////
T_point  vect(T_point  A, T_point  B)
{
    return B - A;
}
/////////////////////////////////////////////////////////////////////////////////////
struct  T_polar_corner_compare
{   
    bool  operator() (T_point A, T_point B)
    {
        return equal_to_for_real(arg(A), arg(B)) 
                   ? less_for_real(abs(A), abs(B)) 
                   : less_for_real(arg(A), arg(B));
    }
};
/////////////////////////////////////////////////////////////////////////////////////
T_coord  det(T_point A, T_point B)
{
    return  A.real() * B.imag() - A.imag() * B.real();
}
/////////////////////////////////////////////////////////////////////////////////////
T_points  get_convex_hull_points(const T_points&  points)
{
    //Ищем выпуклую оболочку методом Грэхема (время работы O(n*lg(n))).
    
    //Находим левую из самых нижних точек заданной совокупности.
    T_point  bottom_point 
        = *std::min_element(points.begin(), points.end(), T_bottom_left_compare());    
    
    //Вычитаем из всех точек вектора точку bottom_point (тогда стартовая точка
    //переместится в начало координат) и записываем эти точки в множество, 
    //отсортированное по полярному углу.
    typedef std::set<T_point, T_polar_corner_compare>  T_convex_hull_points;
    T_convex_hull_points  convex_hull_points;
    
    std::transform(points.begin(), points.end(), 
                   std::inserter(convex_hull_points, convex_hull_points.begin()), 
                   std::bind2nd(std::minus<T_point>(), bottom_point));
 
    bottom_point = T_point();
 
    //Помещаем в стек стартовую точку и первую точку множества, удаляя их из множества.    
    T_points  stack;
 
    T_point  cur_point = bottom_point;
    stack.push_back           (cur_point);
    convex_hull_points.erase  (cur_point);
 
    cur_point = *convex_hull_points.begin();
    stack.push_back           (cur_point);
    convex_hull_points.erase  (cur_point);
 
    //В цикле проверяем, какой поворот образуют точки предпоследняя в стеке,
    //последняя в стеке, и текущая. Если это не левый поворот, то выталкиваем
    //точку из стека (если она там не одна), и вставляем туда текущую. 
    //В конце в стеке останутся точки оболочки.
    for(T_convex_hull_points::const_iterator  point_it = convex_hull_points.begin();
        point_it != convex_hull_points.end(); )
    {
        int last_ind       = stack.size()  - 1;
        int prev_last_ind  = last_ind      - 1;
        T_point  v1 = vect(stack[prev_last_ind], stack[last_ind]);    
        T_point  v2 = vect(stack[last_ind], *point_it); 
 
        if(det(v1, v2) <= 0)
        {
            stack.pop_back();
            if(1 < stack.size())
            {
                continue;
            }            
        }
        stack.push_back(*point_it);
        ++point_it;
    }    
    return  stack;  
}
/////////////////////////////////////////////////////////////////////////////////////
T_coord  get_max_triangle_square(const T_points&  points)
{
    T_points  convex_hull_points = get_convex_hull_points(points);
    if(convex_hull_points.size() < 3)
    {
        return 0;
    }
    //Перебираем все тройки выпуклой оболочки, и выбираем с наибольшей площадью треугольника.
    T_coord  S_max = 0;
    for(T_points::const_iterator  it_A = convex_hull_points.begin();
        it_A != convex_hull_points.end(); ++it_A)
    {
        for(T_points::const_iterator  it_B = it_A + 1;
            it_B != convex_hull_points.end(); ++it_B)
        {
            for(T_points::const_iterator  it_C = it_B + 1;
                it_C != convex_hull_points.end(); ++it_C)
            {
                T_point AB = vect(*it_A, *it_B);
                T_point AC = vect(*it_A, *it_C);
                T_coord S = abs(det(AB, AC)) / 2.0;
                if(S_max == 0
                   || S_max < S)
                {
                    S_max = S;
                }
            }        
        }    
    }
    return  S_max;
}
/////////////////////////////////////////////////////////////////////////////////////
int main()
{
    std::locale::global(std::locale(""));
    srand(static_cast<unsigned>(time(0)));
 
    const int N_min = 1;
    const int N_max = 650;
    
    int n = 0;
    do
    {
        std::cout << "n = ";    
        std::cin >> n;
    }while(n < N_min 
           || N_max < n);
    
    T_points  points(n);
    get_points(points);
    std::cout << "Максимальная площадь треугольника из трех точек множества равна "
              << (n < 3 ? 0 : get_max_triangle_square(points))
              << std::endl;
}

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

12   голосов , оценка 3.917 из 5
Похожие ответы