3.保卫菜地

文章介绍了如何用C++编写代码,计算给定树坐标中形成最小面积围栏的算法,涉及向量和几何计算。输出结果是面积,或者“no”表示无法形成闭合区域。
摘要由CSDN通过智能技术生成
  • 编程语:C++
  • 单个测试集评测时长限制:3秒
题目描述

小明正在给他父亲种地。作为一个精细的男孩,他不能容忍菜地被其他动物践踏。他注意到草地上有 N 棵树,编号从 1 到 N,小明计算了它们的笛卡尔坐标 (Xi​,Yi​)。为了菜地安全,最简单的方法是将一些树木用围栏连接起来,它们形成的封闭区域就是菜地区。小明希望这个区域的面积尽可能小,当然不能是零。

输入格式

第一行包含一个整数 N(1≤N≤100),表示树的数量。 下面的 N 行描述了这些树的坐标。每一行包含两个浮点数 Xi​Yi​(−1000≤Xi​,Yi​≤1000),表示相应树的坐标,这些树的坐标不一致。浮点数之间以空格间隔,且保留到小数点后两位。

输出格式

针对输入,若存在最小区域面积 S,请输出 SS 为浮点数且保留小数点后两位。如果不存在这样的区域,请输出“no”。

输入输出样例

输入样例1

 
  1. 4
  2. -1.00 0.00
  3. 0.00 -3.00
  4. 2.00 0.00
  5. 2.00 2.00

输出样例1 2.00

输入样例2

 
  1. 2
  2. 1.00 2.00
  3. -1.00 3.00

输出样例2 no

说明/提示
样例说明

两个坐标点无法形成闭合区域。

#include <iostream>
#include <vector>
#include <cmath>
#include <climits>
#include <iomanip>

struct Point {
    double x, y;
};

// 计算两个点的向量叉积
double crossProduct(const Point &A, const Point &B, const Point &C) {
    return (A.x * (B.y - C.y) + B.x * (C.y - A.y) + C.x * (A.y - B.y));
}

// 计算三角形的面积
double triangleArea(const Point &A, const Point &B, const Point &C) {
    return std::abs(0.5 * crossProduct(A, B, C));
}

// 计算点之间的距离
double distance(const Point &A, const Point &B) {
    return std::sqrt((A.x - B.x) * (A.x - B.x) + (A.y - B.y) * (A.y - B.y));
}

int main() {
    int N;
    std::cin >> N;
    
    std::vector<Point> points(N);
    for (int i = 0; i < N; ++i) {
        std::cin >> points[i].x >> points[i].y;
    }

    double minArea = 1e9; // 初始化最小面积为一个非常大的数
    bool found = false;

    // 枚举所有可能的三点组合
    for (int i = 0; i < N - 2; ++i) {
        for (int j = i + 1; j < N - 1; ++j) {
            for (int k = j + 1; k < N; ++k) {
                double area = triangleArea(points[i], points[j], points[k]);
                if (area > 0 && area < minArea) { // 确保面积是正的且比之前的最小面积小
                    minArea = area;
                    found = true;
                }
            }
        }
    }

    if (found) {
        std::cout << std::fixed << std::setprecision(2) << minArea << std::endl;
    } else {
        std::cout << "no" << std::endl;
    }

    return 0;
}

  • 6
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值