题目描述
Farmer John 想要给他的奶牛们建造一个三角形牧场。
有 N 个栅栏柱子分别位于农场的二维平面上不同的点 (X1,Y1)…(XN,YN)。
他可以选择其中三个点组成三角形牧场,只要三角形有一条边与 x 轴平行,且有另一条边与 y 轴平行。
Farmer John 可以围成的牧场的最大面积是多少?
保证存在至少一个合法的三角形牧场。
输入格式
输入的第一行包含整数 N。
以下 N 行每行包含两个整数 Xi 和 Yi,均在范围 −104…104 之内,描述一个栅栏柱子的位置。
输出格式
由于面积不一定为整数,输出栅栏柱子可以围成的合法三角形的最大面积的两倍。
数据范围
3≤N≤100
样例
输入样例:
4
0 0
0 1
1 0
1 2
输出样例:
2
样例解释
位于点 (0,0)、(1,0) 和 (1,2) 的木桩组成了一个面积为 1 的三角形。所以,答案为 2⋅1=2。
只有一个其他的三角形,面积为 0.5。
思路一:
(暴力枚举)
直角三角形面积公式 s = l*h/2
本题答案是求面积的2倍
时间复杂度 o(n^3)
参考文献
C++ 代码
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 120;
int n,res=-10;
int x[N],y[N];
int main()
{
cin>>n;
for (int i = 1; i <= n; i ++ )cin>>x[i]>>y[i];
for (int i = 1; i <= n; i ++ )
for (int j = 1; j <= n; j ++ )
for (int k = 1; k <= n; k ++ )
if(x[i]==x[j]&&y[i]==y[k])
{
int s = (y[i]-y[j])*(x[k]-x[i]);
res=max(abs(s),res);
}
return cout<<res,0;
}
Java代码
import java.util.*;
import java.io.*;
public class Main{
static int res;
static int x[]=new int [120];
static int y[]=new int [120];
public static void main(String[] args) {
Scanner cin = new Scanner(System.in);
int n = cin.nextInt();
for (int i = 1; i <= n; i ++ )
{
x[i]=cin.nextInt();
y[i]=cin.nextInt();
}
for (int i = 1; i <= n; i ++ ) {
for (int j = 1; j <= n; j++) {
for (int k = 1; k <= n; k++) {
if (x[i] == x[j] && y[i] == y[k]) {
int s = (y[i] - y[j]) * (x[k] - x[i]);
res = Math.max(Math.abs(s), res);
}
}
}
}
System.out.println(res);
return ;
}
}
python3代码
def main():
n = int(input())
list1 = []
for i in range(n):
x,y = map(int, input().split())
list1.append((x, y))
ans = 0
for i in range(n):
for j in range(n):
(x1, y1) = list1[i]
(x2, y2) = list1[j]
if(list1.count((x1, y2))):
area = abs(x1 - x2) * abs(y1 - y2)
ans = max(ans, area)
print(ans)
if __name__=="__main__":
main()
GO代码
package main
import (
"bufio"
. "fmt"
"os"
)
var points [110][2]int
func main() {
in := bufio.NewReader(os.Stdin)
out := bufio.NewWriter(os.Stdout)
defer out.Flush()
var n int
Fscan(in, &n)
for i := 0; i < n; i++ {
var x, y int
Fscan(in, &x, &y)
points[i] = [2]int{x, y}
}
res := 0
for i := 0; i < n; i++ {
for j := 0; j < n; j++ {
for k := 0; k < n; k++ {
if i != j && j != k && i != k {
if points[i][0] == points[j][0] && points[j][1] == points[k][1] {
res = max(res, abs(points[j][0]-points[k][0]) * abs(points[j][1]-points[i][1]))
}
}
}
}
}
Fprintln(out, res)
}
func max(a, b int) int {
if a > b {
return a
}
return b
}
func abs(x int) int {
if x < 0 {
return -x
}
return x
}
思路二:
海伦——秦九韶三角形中线面积公式
p = (a + b + c)/2;//a,b,c为三角形三条边
s=sqrt(p(p-a)(p-b)(p-c))
注意这里存在精度问题
下面就不转码了,累了
时间复杂度 O(n^3)
参考文献
C++ 代码
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const int N = 120;
double n,res;
double x[N],y[N];
double length(double x1,double y1,double x2,double y2)
{
return sqrt((y1-y2)*(y1-y2)+(x1-x2)*(x1-x2));
}
int main()
{
cin>>n;
for (int i = 1; i <= n; i ++ )
{
int a,b;
cin>>a>>b;
x[i]=a+1e4;
y[i]=b+1e4;
}
for (int i = 1; i <= n; i ++ )
for (int j = i+1; j <= n; j ++ )
for (int k = j+1; k <= n; k ++ )
{
if(x[i] != x[j] && x[i] != x[k] && x[j] != x[k]) continue;
if(y[i] != y[j] && y[i] != y[k] && y[j] != y[k]) continue;
double a = length(x[i],y[i],x[j],y[j]);
double b = length(x[i],y[i],x[k],y[k]);
double c = length(x[j],y[j],x[k],y[k]);
double p = (a+b+c)/2;
double s = sqrt(p*(p-a)*(p-b)*(p-c));
res = max(res,2*s);
}
cout << (long long)(res + 0.000001) << endl;
return 0;
}
思路三:
正弦定理求面积
cos_a = (b*b + c*c -a *a)/2/b/c;//a,b,c为三角形三条边
s=b*c*sin_a/2
注意这里存在精度问题
时间复杂度 O(n^3)
参考文献
C++ 代码
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const int N = 120;
double n,res;
double x[N],y[N];
double length(double x1,double y1,double x2,double y2)
{
return sqrt((y1-y2)*(y1-y2)+(x1-x2)*(x1-x2));
}
int main()
{
cin>>n;
for (int i = 1; i <= n; i ++ )
{
int a,b;
cin>>a>>b;
x[i]=a+1e4;
y[i]=b+1e4;
}
for (int i = 1; i <= n; i ++ )
for (int j = i+1; j <= n; j ++ )
for (int k = j+1; k <= n; k ++ )
{
if(x[i] != x[j] && x[i] != x[k] && x[j] != x[k]) continue;
if(y[i] != y[j] && y[i] != y[k] && y[j] != y[k]) continue;
double a = length(x[i],y[i],x[j],y[j]);
double b = length(x[i],y[i],x[k],y[k]);
double c = length(x[j],y[j],x[k],y[k]);
double cos_a = (b*b+c*c-a*a)/(2*b*c);
double sin_a = sqrt(1-cos_a*cos_a);
double s = c*b*sin_a/2;
res = max(res,s*2);
}
cout << (long long)(res + 0.000001) << endl;
return 0;
}
向量以及其他上式的变形的方法这里就不写了,基本上都一样
欢迎点赞留言
嗷嗷嗷~