swust Max Area

Max Area

    Time Limit: 1000 ms 

    Memory Limit: 65535 kB 

    Description

         在笛卡尔坐标系正半轴(x>=0,y>=0)上n个点,给出了这些  横坐标和纵坐标,但麻烦的是这些点的坐标没有配对好,你的任务就是  将这n个点的横坐标和纵坐标配对好,使得这n个点与x轴围成的面积   大。 

    Input

在数据的第一行有一个正整数m,表示有m组测试实例。接下来有m行,每行表示一组测试实例。每行的第一个数n,表示给出了n个点,接着给出了nx坐标和y坐标。(给出的x轴的数据不会重复,y轴数据也不会重复)(m<5000, x y< 10,000,000, 1 < n <= 1000)
Output

输出所计算的最大面积,结果保留两位小数,每组数据占一行。 

Sample Input

2

4 0 1 3 5 1 2 3 4

6 14 0 5 4 6 8 1 5 6 2 4 3

Sample Output

15.00

59.00


此题是一道几何题,同时也是代数方法求解几何题的典型题,这也为我们解题提供了一种思路可以将题目描述转换为代数描述,然后从代数的角度去求解问题。

假设,我们所求图形的坐标依次为(X1, Y1), (X2, Y2)。。。。。。(Xn,Yn)。

由图形我们很容易知道,该图形的面积为n个梯形的面积之和。

假设图形的面积为area

2*area = (X2 - X1)*(Y1+Y2) + (X3-X2)*(Y2+Y3)+。。。。。。+(Xn-X(n-1))*(Yn-Y(n-1))

化简一下即2*area = (X2-X1)*Y1 + (X3-X1)*Y2+。。。。。。。。。+(X(i+1)-X(i-1))*Yi+。。。。。(Xn-X(n-1))*Yn

我们的目标是使area到达最大值。

而,当X坐标给定时,所有的Y未知数的系数也就给定了,所以我们要做的就是使最大的系数乘以最大的Y坐标值,然后加起来,这样得到的area可以达到最大值。

所以就是将系数排序,然后将Y坐标排序,然后对应相乘,累加就可以得到area值。算法复杂度为nlogn


代码如下

#include <cstdio>
#include <algorithm>
using namespace std;
 
const int max_n = 1010;
 
int main()
{
 	int m, n;
 	double x[max_n], y[max_n], high[max_n], ans;
 	scanf("%d", &m);
 	while ( m-- )
 	{
 		scanf("%d", &n);
 		for ( int i = 0; i < n; ++i )
 		{
 			scanf("%lf", &x[i]);
 		}
 		for ( int i = 0; i < n; ++i )
 		{
 			scanf("%lf", &y[i]);
 		}
 		sort(x, x + n);
 		sort(y, y + n);
 		high[0] = x[1] - x[0];
 		high[n-1] = x[n-1] - x[n - 2];
 		for ( int i = 1; i < n - 1; ++i )
 		{
 			high[i] = x[i + 1] - x[i - 1];
 		}
 		sort(high, high + n);
 		ans = 0.0;
 		for ( int i = 0; i < n; ++i )
 		{
 			ans += high[i] * y[i];
 		}
 		printf("%.2lf\n", ans/2.0);
 	}
 	return 0;
}
 


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值