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个点,接着给出了n个x坐标和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; }