- 编程语:C++
- 单个测试集评测时长限制:3秒
题目描述
小明正在给他父亲种地。作为一个精细的男孩,他不能容忍菜地被其他动物践踏。他注意到草地上有 N 棵树,编号从 1 到 N,小明计算了它们的笛卡尔坐标 (Xi,Yi)
。为了菜地安全,最简单的方法是将一些树木用围栏连接起来,它们形成的封闭区域就是菜地区。小明希望这个区域的面积尽可能小,当然不能是零。
输入格式
第一行包含一个整数 N(1≤N≤100)
,表示树的数量。 下面的 N
行描述了这些树的坐标。每一行包含两个浮点数 Xi
和 Yi(−1000≤Xi,Yi≤1000)
,表示相应树的坐标,这些树的坐标不一致。浮点数之间以空格间隔,且保留到小数点后两位。
输出格式
针对输入,若存在最小区域面积 S
,请输出 S
,S
为浮点数且保留小数点后两位。如果不存在这样的区域,请输出“no”。
输入输出样例
输入样例1
4
-1.00 0.00
0.00 -3.00
2.00 0.00
2.00 2.00
输出样例1 2.00
输入样例2
2
1.00 2.00
-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;
}