zoukankan      html  css  js  c++  java
  • 【dog与lxy】8.25题解-land

    land


    题目描述

    dog终于有了一块领地,但是现在可怜的dog面临着lxy的入侵,于是他决定在自己的领地设置炮楼来保卫自己免受QJ。现在dog找到它可以在领地上设置炮楼的N个地点。但是留给dog的时间不多了,dog决定赶快建4个炮楼。而现在的问题是dog希望这4个炮楼的防守区域最大。而4个炮楼的防守区域就是这4个炮楼的多边形的面积。Dog马上找到了你,请你帮助他,而你不忍心让dog惨遭蹂躏,那么请告诉dog他的防守区域最大为多少。(保证最终得到的防守区域是凸四边形)

    输出输出

    输入文件:
    第1行1个数n,表示可能修建炮楼的位置。接下来n行,每行2个数x,y,表示可能的炮楼的位置。(不考虑地球曲面的影响,默认为dog的领地是块平面,然后建立直角坐标系,给出的就是直角坐标系上的位置)。

    输出文件:
    dog他的防守区域最大为多少。精确到小数点后3位。

    样例

    输入

    5
    0 0
    1 0
    1 1
    0 1
    0.5 0.5
    

    输出

    1
    

    说明

    数据范围

    100%的数据中,n<=2000,|x|,|y|<=100000.
    50%的数据中,n<=1000, |x|,|y|<=10000.
    30%的数据中,n<=50, |x|,|y|<=100.

    思路

    给出点集S,要求从S中选出4个点,使得这四个点组成的四边形面积最大(S<=2000)
    如果最终得到的是凸四边形,题目就好做得多了。
    对于这一题数据较小,O(n^2)的复杂度是能够AC的。

    优美的暴力

    1. 对于第一个点,找出离它最远的点,连接这两个点成一个线段
    2. 枚举每一个点,分别找出线段两边距离线段最远的点
    3. 用叉乘或者分割成两个三角形计算四边形的面积
    4. 与最大值比较,更新最大值
    5. 对于第二个点,第三个······重复操作

    代码

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #define MAXX 2000+5
    using namespace std;
    int n,maxnum,maxup,maxunder;
    double x[MAXX],y[MAXX],k,b;
    inline void search(int p){
    	double maxn=-1000;
    	for(int i=1;i<=n;i++){
    		if(i==p) continue;
    		if(maxn<sqrt((x[i]-x[p])*(x[i]-x[p])+(y[i]-y[p])*(y[i]-y[p]))){
    			maxn=sqrt((x[i]-x[p])*(x[i]-x[p])+(y[i]-y[p])*(y[i]-y[p]));
    			maxnum=i;
    		}
    	}
    }
    inline void fangcheng(int i){
    	k=(y[i]-y[maxnum])/(x[i]-x[maxnum]);
    	b=y[i]-k*x[i];
    }
    inline void runup(int p){
    	double maxn=-1000;
    	for(int i=1;i<=n;i++){
    		if(i==p) continue;
    		if(x[i]*k+b>=y[i]) continue;
    		if(maxn<(abs(k*x[i]-y[i]+b)/sqrt(k*k+1))){
    			maxn=(abs(k*x[i]-y[i]+b)/sqrt(k*k+1));
    			maxup=i;
    		}
    	}
    }
    inline void rununder(int p){
    	double maxn=-1000;
    	for(int i=1;i<=n;i++){
    		if(i==p) continue;
    		if(x[i]*k+b<=y[i]) continue;
    		if(maxn<(abs(k*x[i]-y[i]+b)/sqrt(k*k+1))){
    			maxn=(abs(k*x[i]-y[i]+b)/sqrt(k*k+1));
    			maxunder=i;
    		}
    	}
    }
    inline double get_s(int i){
    	double s=0;
    	s+=x[i]*y[maxup]-x[maxup]*y[i];
    	s+=x[maxup]*y[maxnum]-x[maxnum]*y[maxup];
    	s+=x[maxnum]*y[maxunder]-x[maxunder]*y[maxnum];
    	s+=x[maxunder]*y[i]-x[i]*y[maxunder];
    	s*=0.5;
    	s=abs(s);
    	return s;
    }
    int main(){
    	freopen("Land.in","r",stdin);
    	freopen("Land.out","w",stdout);
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++)
    		scanf("%lf%lf",&x[i],&y[i]);
    	double ans=-1;
    	for(int i=1;i<=n;i++){
    		search(i);
    		fangcheng(i);
    		runup(i);
    		rununder(i);
    		ans=max(get_s(i),ans);
    	}
    	printf("%.3lf",ans);
    	return 0;
    } 
    
  • 相关阅读:
    垂死挣扎还是涅槃重生 -- Delphi XE5 公布会归来感想
    自考感悟,话谈备忘录模式
    [每日一题] OCP1z0-047 :2013-07-26 alter table set unused之后各种情况处理
    Java实现 蓝桥杯 算法提高 p1001
    Java实现 蓝桥杯 算法提高 拿糖果
    Java实现 蓝桥杯 算法提高 拿糖果
    Java实现 蓝桥杯 算法提高 求arccos值
    Java实现 蓝桥杯 算法提高 求arccos值
    Java实现 蓝桥杯 算法提高 因式分解
    Java实现 蓝桥杯 算法提高 因式分解
  • 原文地址:https://www.cnblogs.com/bbqub/p/7428468.html
Copyright © 2011-2022 走看看