Cows+礼品包裹解决凸包问题+求最大面积

奶牛

时间限制: 2000MS

 

内存限制: 65536K

提交总数: 12082

 

接受: 5237

描述

你在南方的朋友有兴趣建造栅栏并将犁头变成剑。为了帮助他的海外冒险,他们被迫通过尽可能使用树木作为围栏柱来购买围栏岗位。考虑到一些树木的位置,您将帮助农民尝试创造可能的最大牧场。并非所有树木都需要使用。

但是,因为您将自己监督牧场的建设,所有农民都想知道他们可以在牧场放多少头奶牛。众所周知,一头母牛需要至少50平方米的牧场才能生存。

输入

输入的第一行包含一个整数,Ñ(1≤ Ñ ≤10000),含有该生长的可用土地上树的数量。接下来的n行包含每个树的整数坐标,以两个整数xy分隔一个空格(其中-1000≤x,y≤1000)。整数坐标精确地与以米为单位的距离相关联(例如,坐标(10; 11)和(11; 11)之间的距离是一米)。

产量

您将输出一个整数值,即可以使用可用树构建的最大字段上可以存活的奶牛数量。

样本输入

4

0 0

0 101

75 0

75 101

样本输出

151

资源

CCC 2007

分析:求凸包+利用叉乘求面积

代码:

/**
 * 
 * 凸包:求面积
 * 奶牛多少个
 * AC通过
 * 
 */

import java.util.ArrayList;
import java.util.Scanner;

public class Main {
	
	static double x[];
	static double y[];
	static int n;
	//这是存凸包点的一种方式
	static int count;//表示凸包数组中有count个元素
	static int ch[]=new int [n];
	//这是存凸包点的第二种方式
	static ArrayList<Integer> a=new ArrayList();
	
	public static void main(String[] args) {
		Scanner sc=new Scanner(System.in);
		n=sc.nextInt();
		x=new double[n];
		y=new double[n];
		for(int i=0;i<n;i++)
		{
			x[i]=sc.nextDouble();
			y[i]=sc.nextDouble();
			
		}
		
		baoguo();
		double s=0;
	
		for(int i=2;i<a.size();i++)
		{
			//利用凸包的点求面积
			s+=d(a.get(0),a.get(i-1),a.get(i))/2;
			
		}
	
		System.out.println((int)s/50);

	}
	//给我Point点的位置即可
	static double  d(int a,int b,int c)
	{
		return Math.abs((x[b]-x[a])*(y[c]-y[a])-(x[c]-x[a])*(y[b]-y[a]));
	}
	static int Direction(int a,int b,int c)
	{
		double d=(x[b]-x[a])*(y[c]-y[a])-(x[c]-x[a])*(y[b]-y[a]);
		if(d==0) return 0;
		else if(d>0) return 1;
		else return -1;
	}
	static double Distance(int a,int b)
	{
		return Math.sqrt((x[b]-x[a])*(x[b]-x[a])+(y[b]-y[a])*(y[b]-y[a]));
	}
	static void baoguo()
	{
		//选最左最下的点
		int index=0;//标记最左最小下标
		double min=x[0];
		int tmp;
		int k;
		for(int i=0;i<n;i++)
		{
			if(min>x[i]||min==x[i]&&y[index]>y[i])
			{
				min=x[i];
				index=i;
			}
		}
		tmp=index;
		while(true)
		{
			k=-1;
			a.add(index);
			
			for(int i=0;i<n;i++)
			{
				if(i!=index&&(k==-1||(Direction(index,i,k)>0||Direction(index,i,k)==0&&(Distance(index,k)<Distance(index,i)))))
				{
					k=i;
				}
			}
			if(k==tmp)
				break;
			index=k;
		}
	}
	
	
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值