POJ 1271 && uva 10117 Nice Milk

题意:给你一个凸多边形的面包,然后告诉你牛奶的高度,和可以进行最多k次蘸牛奶,求面包最多能蘸到牛奶的面积

思路:dfs枚举边,然后向内推进h,用半平面交求不能蘸到牛奶的面积,用总面积减去面积,维护最大值

有一个小trick:k有可能会比边大,需要判断一下;

不得不说不知道是uva的机器比poj好还是数据比poj少,uva上只跑了300ms,而poj接近600ms。。。。。

#include
#include
#include
#include
#include
#include
#define inf 0x7ffffff
using namespace std;
const double eps=1e-8;
int n,k,h,top,bot,dq[1000000];
int ln;
double ans,area,marea;
struct P
{
	double x,y;
	P(){}
	P(double x,double y):x(x),y(y){
	}
	P operator +(P p){
		return P(x+p.x,y+p.y);
	}
	P operator -(P p){
		return P(x-p.x,y-p.y);
	}
	P operator *(double d){
		return P(x*d,y*d);
	}
	double det(P p){
		return x*p.y-y*p.x;
	}
};
P p[1000000],s[1000000];
struct Line
{
	P a,b;
	double angle;
};
Line l[1000000],l1[1000000],l2[1000000];
int dblcmp(double k)
{
	if(fabs(k)0?1:-1;
}
P in(Line a,Line b){  
	return a.a+(a.b-a.a)*((b.b-b.a).det(b.a-a.a)/(b.b-b.a).det(a.b-a.a));  
}  
bool judge(Line a,Line b,Line c){  
	P r=in(b,c);  
	return dblcmp((a.a-r).det(a.b-r))<0;  //顺时针大于0,逆时针小于0;  
}
bool cmp(Line a,Line b){  
	int d=dblcmp(a.angle-b.angle);  
	if(!d)  
		return dblcmp((b.a-a.a).det(b.b-a.a))>0;  
	return d<0;  
}
double dis(P a,P b)
{
	double c=(a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
	return sqrt(c);
}
void getarea()
{
	area=0;
	for(int i=0;i0)  
			l2[++j]=l2[i];  
	}  
	int len=j+1;  
	top=1;  
	bot=0;  
	dq[0]=0;  
	dq[1]=1;  
	for(i=2;ibot && judge(l2[i],l2[dq[top]],l2[dq[top-1]])) top--;  
		while(top>bot && judge(l2[i],l2[dq[bot]],l2[dq[bot+1]])) bot++;  
		dq[++top]=i;  
	}  
	while(top>bot && judge(l2[dq[bot]],l2[dq[top]],l2[dq[top-1]])) top--;  
	while(top>bot && judge(l2[dq[top]],l2[dq[bot]],l2[dq[bot+1]])) bot++;
	dq[++top]=dq[bot];
	int pn=0;
	for(pn=0,i=bot;i=3)
	{
		marea=0;  
		for(int i=0;iln)
		return;
	if(num==k)
	{
		solve();
		return ;
	}
	for(int i=index;iln)
			k=ln;
		sort(l,l+ln,cmp);
		sort(l1,l1+ln,cmp);
		getarea();
		double r=(double)h;
		dfs(0,0,r);
		printf("%.2lf\n",ans);
	}
	return 0;
}


你可能感兴趣的:(学生时代刷题归档)