以下是用C++实现的程序,可以生成随机的线段并找出最短的一条。程序使用了Qt库来创建可执行界面,并使用了QPainter来绘制线段和标记最短路线。

#include <QApplication>
#include <QWidget>
#include <QPushButton>
#include <QMessageBox>
#include <QPainter>
#include <vector>
#include <random>
#include <algorithm>
#include <cmath>

struct Point {
    int x;
    int y;
};

struct Line {
    Point start;
    Point end;
};

class Widget : public QWidget {
public:
    Widget(QWidget *parent = nullptr) : QWidget(parent), n(0), linesGenerated(false) {
        setFixedSize(800, 600);
        setWindowTitle('Shortest Line');

        generateButton = new QPushButton('Generate Lines', this);
        generateButton->setGeometry(10, 10, 120, 30);
        connect(generateButton, &QPushButton::clicked, this, &Widget::generateLines);

        shortestButton = new QPushButton('Find Shortest', this);
        shortestButton->setGeometry(10, 50, 120, 30);
        shortestButton->setEnabled(false);
        connect(shortestButton, &QPushButton::clicked, this, &Widget::findShortest);

        resetButton = new QPushButton('Reset', this);
        resetButton->setGeometry(10, 90, 120, 30);
        resetButton->setEnabled(false);
        connect(resetButton, &QPushButton::clicked, this, &Widget::reset);

        messageBox = new QMessageBox(this);
        messageBox->setStandardButtons(QMessageBox::Ok);
        messageBox->setDefaultButton(QMessageBox::Ok);
        messageBox->setWindowTitle('Result');

        generator.seed(std::random_device()());

        generateLines();
    }

    void generateLines() {
        n = std::uniform_int_distribution<int>(10, 40)(generator);
        lines.clear();

        std::uniform_int_distribution<int> xDist(50, width() - 50);
        std::uniform_int_distribution<int> yDist(150, height() - 50);

        Point startPoint = {50, 50};
        Point endPoint = {width() - 50, height() - 50};

        generateLineSegments(startPoint, endPoint, n);

        linesGenerated = true;
        shortestButton->setEnabled(true);
        resetButton->setEnabled(true);
        update();
    }

    void findShortest() {
        if (!linesGenerated) {
            return;
        }

        Line shortestLine;
        double shortestDistance = std::numeric_limits<double>::max();

        for (const auto& line : lines) {
            double distance = calculateDistance(line);

            if (distance < shortestDistance && !isLineCovered(line)) {
                shortestDistance = distance;
                shortestLine = line;
            }
        }

        if (shortestDistance == std::numeric_limits<double>::max()) {
            messageBox->setText('No shortest line found.');
        } else {
            messageBox->setText(QString('Shortest line found: (%1, %2) - (%3, %4)
Distance: %5')
                                .arg(shortestLine.start.x)
                                .arg(shortestLine.start.y)
                                .arg(shortestLine.end.x)
                                .arg(shortestLine.end.y)
                                .arg(shortestDistance));
        }

        messageBox->show();
    }

    void reset() {
        linesGenerated = false;
        shortestButton->setEnabled(false);
        resetButton->setEnabled(false);
        update();
    }

protected:
    void paintEvent(QPaintEvent *) override {
        QPainter painter(this);

        painter.setPen(Qt::black);

        if (linesGenerated) {
            for (const auto& line : lines) {
                painter.drawLine(line.start.x, line.start.y, line.end.x, line.end.y);
            }

            if (shortestButton->isEnabled()) {
                Line shortestLine;
                double shortestDistance = std::numeric_limits<double>::max();

                for (const auto& line : lines) {
                    double distance = calculateDistance(line);

                    if (distance < shortestDistance && !isLineCovered(line)) {
                        shortestDistance = distance;
                        shortestLine = line;
                    }
                }

                painter.setPen(Qt::red);
                painter.setBrush(Qt::red);
                painter.setRenderHint(QPainter::Antialiasing, true);
                painter.setRenderHint(QPainter::HighQualityAntialiasing, true);
                painter.setRenderHint(QPainter::TextAntialiasing, true);
                painter.setRenderHint(QPainter::SmoothPixmapTransform, true);
                painter.setRenderHint(QPainter::NonCosmeticDefaultPen, true);
                painter.setRenderHint(QPainter::Qt4CompatiblePainting, true);
                painter.setRenderHint(QPainter::LosslessImageRendering, true);
                painter.setRenderHint(QPainter::Antialiasing, true);
                painter.setRenderHint(QPainter::TextAntialiasing, true);
                painter.setRenderHint(QPainter::SmoothPixmapTransform, true);

                painter.drawLine(shortestLine.start.x, shortestLine.start.y, shortestLine.end.x, shortestLine.end.y);
            }
        }
    }

private:
    void generateLineSegments(const Point& startPoint, const Point& endPoint, int n) {
        std::uniform_int_distribution<int> dist(0, 1);

        Point currentPoint = startPoint;

        for (int i = 0; i < n; ++i) {
            Line line;
            line.start = currentPoint;

            if (i == n - 1) {
                line.end = endPoint;
            } else {
                Point nextPoint;
                nextPoint.x = std::uniform_int_distribution<int>(currentPoint.x - 100, currentPoint.x + 100)(generator);
                nextPoint.y = std::uniform_int_distribution<int>(currentPoint.y - 100, currentPoint.y + 100)(generator);
                line.end = nextPoint;
                currentPoint = nextPoint;
            }

            lines.push_back(line);
        }
    }

    double calculateDistance(const Line& line) {
        return std::sqrt(std::pow(line.start.x - line.end.x, 2) + std::pow(line.start.y - line.end.y, 2));
    }

    bool isLineCovered(const Line& line) {
        for (const auto& otherLine : lines) {
            if (line.start.x == otherLine.start.x &&
                line.start.y == otherLine.start.y &&
                line.end.x == otherLine.end.x &&
                line.end.y == otherLine.end.y) {
                continue;
            }

            if (line.start.x >= otherLine.start.x && line.start.x <= otherLine.end.x &&
                line.start.y >= otherLine.start.y && line.start.y <= otherLine.end.y &&
                line.end.x >= otherLine.start.x && line.end.x <= otherLine.end.x &&
                line.end.y >= otherLine.start.y && line.end.y <= otherLine.end.y) {
                return true;
            }
        }

        return false;
    }

    int n;
    std::vector<Line> lines;
    std::default_random_engine generator;
    QPushButton *generateButton;
    QPushButton *shortestButton;
    QPushButton *resetButton;
    QMessageBox *messageBox;
    bool linesGenerated;
};

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);
    Widget w;
    w.show();
    return app.exec();
}
C++实现线段最短路径查找程序,并可视化显示

原文地址: https://www.cveoy.top/t/topic/o2m9 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录