0

Estoy tratando de resolver el siguiente problema de Omegaup:

Escribe un programa que, dadas las coordenadas de los vértices de un cuadrilátero, calcule la longitud de su lado más corto.

Entrada Ocho reales x1,y1,x2,y2,x3,y3,x4,y4. Puedes suponer que 0 ≤xi,yi≤ 1000 y que los vértices se listan ordenados en el sentido de las manecillas del reloj.

Salida Un real que sea la longitud del lado más corto del cuadrilátero.

Para lo cual escribí el siguiente código, pero al subirlo, me aparece que la respuesta es incorrecta. ¿Qué está mal en el código?

#include <iostream>
#include <cmath>
using namespace std;
int main(void){
    int x1;
    int y1;
    int x2;
    int y2;
    int x3;
    int y3;
    int x4;
    int y4;
    cin >> x1;
    cin >> y1;
    cin >> x2;
    cin >> y2;
    cin >> x3;
    cin >> y3;
    cin >> x4;
    cin >> y4;
    double lados[4];
    lados[0] = sqrt(pow((y2 - y1), 2) + pow((x2 - x1), 2));
    lados[1] = sqrt(pow((y3 - y2), 2) + pow((x3 - x2), 2));
    lados[2] = sqrt(pow((y4 - y3), 2) + pow((x4 - x3), 2));
    lados[3] = sqrt(pow((y1 - y4), 2) + pow((x1 - x4), 2));

    double ladoMenor = lados[0];
    for(double x : lados){
        if(x < ladoMenor){
            ladoMenor = x;
        }
    }
    cout << ladoMenor;
}
PaperBirdMaster
  • 44,474
  • 6
  • 44
  • 82
  • ¿Ingresando que valores te sale el error? – 4lrdyD Mar 08 '20 at 02:58
  • Es posible que no sea correcta porque ordenados en el sentido de las manecillas del reloj parece implicar que el cuadrilátero deba ser **simplemente conexo** (sus lados no se cortan) y esto quiere decir que haya extremos en x e y por pares alternos, de modo que los 8 valores van a tener restricciones de rango. Y, no se contempla en el algoritmo escrito. La intuición que enuncias tiene sentido. – quevedo Mar 08 '20 at 03:18

2 Answers2

1

¿Qué está mal en el código?

Que asumes que las coordenadas de entrada son enteros.

¿Qué pasa si en uno de los casos una coordenada tiene decimales? Pues eso, que tu programa falla.

Con esto debería pasar:

double x1, y1, x2, y2, x3, y3, x4, y4;
cin >> x1 >> y1 >> x2 >> y2 >> x3 >> y3 >> x4 >> y4;

Ahora bien, si tu intención, una vez que pasa, es mejorar los tiempos te toca optimizar el programa

eferion
  • 49,291
  • 5
  • 30
  • 72
0

¿Qué está mal en el código?

Algunos consejos para mejorar tu código:

  1. En las funciones que no reciben parámetros, deben tener una lista de parámetros vacía (no una lista de parámetros con void).
  2. Es aconsejable que la cláusula using namespace std; tenga el ámbito lo más pequeño posible, estaría mejor dentro de la main que en el ámbito global.
  3. Es aconsejable que main devuelva algo.
  4. Estás programando en C++, que aunque es un lenguaje multiparadigma es conocido por su orientación a objetos, usa objetos:

struct punto { float x{}, y{}; };
struct cuadrilatero { punto esquina[4]{}; };

// Lectura de puntos
std::istream &operator >>(std::istream &i, punto &p)
{
    i >> p.x;
    i >> p.y;
    return i;
}

// Lectura de cuadriláteros
std::istream &operator >>(std::istream &i, cuadrilatero &c)
{
    for (auto &p : c.esquina)
        i >> p;

    return i;
}

Con el código anterior, tu recopilación de datos podría parecerse a:

int main()
{
    cuadrilatero c;
    std::cin >> c;

    // … resto del código

    return 0;
}

Si añadimos el objeto línea, podríamos hacer que el objeto cuadrilatero nos devolviese cada uno de sus lados, si además el objeto línea nos informa de su longitud, tendríamos todas las piezas:

struct linea {
    punto inicio{}, fin{};
    auto modulo() const {
        const auto mx = fin.x - inicio.x;
        const auto my = fin.y - inicio.y;
        return std::sqrt((mx * mx) + (my * my));
    }
};

struct cuadrilatero {
    punto esquina[4]{};
    linea lado(unsigned indice) {
        switch (indice) {
            case 0:
                return {esquina[0], esquina[1]};
            case 1:
                return {esquina[1], esquina[2]};
            case 2:
                return {esquina[2], esquina[3]};
            case 3:
                return {esquina[3], esquina[0]};
        }
        return {};
    }
};

Tu función main podría parecerse a:

int main()
{
    cuadrilatero c;
    std::cin >> c;

    std::cout << "El lado mas corto mide: " << std::min({c.lado(0).modulo(),
                                c.lado(1).modulo(),
                                c.lado(2).modulo(),
                                c.lado(3).modulo()});

    return 0;
}
PaperBirdMaster
  • 44,474
  • 6
  • 44
  • 82
  • Todo esto me resulta bastante complejo, sobre todo los objetos y la lectura de los puntos y cuadriláteros, ya que mis conocimientos de c++ todavía son muy básicos. Pero tras probarlo me he dado cuenta que da una respuesta correcta. Ahora solo trataré de comprenderlo y ser capaz de recrearlo por mi mismo. Muchas gracias. – julio meza Mar 09 '20 at 18:05
  • @juliomeza si tienes dudas nuevas en base a lo que ves en esta respuesta, te animo a hacer nuevas preguntas. – PaperBirdMaster Mar 10 '20 at 09:18