1157. 【GDOI2004】可怜的绵羊 (Standard IO)

1157. 【GDOI2004】可怜的绵羊 (Standard IO)

由于这道题的数据特别小(n<=100),所以我们可以考虑较为暴力的做法。
首先扩倍,由于是按逆时针顺序给出各个树桩所在的坐标,所以。。。是为了后面的方便。。无所谓了。
我们先预处理t[i][j][k]表示以i,j,k为顶点的三角形是否存在即(三角形里不存在毒药),若存在t[i][j][k]=面积,若不存在为0;
我们先考虑如何求t;我们首先可以对于任何一个三角形可以把其分为以下两种

分别记录一下三条线的y=kx+b;然后暴力扫一遍m,然后分类讨论(以第二高的点划分然后,分上下讨论)看一下三角形里有没有毒,若有return0;else return S=sqrt(q(q-a)(q-b)(q-c)); 。。。。。你们有更好的方法就。。。别打击我。
这里理论来说应该是O(n^4)的,可能数据水了,或跑不满剪了许多。

然后设f[i][j]表示i必选以j为结尾i--->j中可划分的最大值(从i开始逆时针到j),我们枚举i,然后逆时针枚举j,每次从i<k<j,中选出k来转移,转移显然;分f[i][j]=max{f[i][j],f[i][k]+t[i][k][j]}不过这里要特判一下,毒药恰好在两个三角形边界上的情况。例如:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
struct nup{int x,y;}a[301],b[101];
int i,j,n,m,bz[201];
double t[202][202][202],ans,ans1,ans2,k,l,r,z,f[211][211];
void in(double &k,double &z,int a,int b,int a1,int b1)
{	
	if(b==b1){k=0,z=b;return;}
	a-=a1;b-=b1;k=a*1.0/b;z=a1-k*b1;	
}
int abss(int x){return(x>0?x:-x);}
double pd(int x,int y,int x1,int y1,int x2,int y2)
{
	if(y<y1){swap(x,x1);swap(y,y1);}if(y<y2){swap(x,x2);swap(y,y2);}
	if(x1>x2){swap(x1,x2);swap(y1,y2);}
	double l,k,r,l1,k1,r1,l2,k2,r2,z,z1,z2;//l=kr+z;
	in(k,z,y,x,y1,x1);  in(k1,z1,y,x,y2,x2);  in(k2,z2,y1,x1,y2,x2);
	if(y1>y2)
	{
		for(int i=1;i<=m;i++)
		{
			if(b[i].y<=y&&b[i].y>=y1)
			{
				double xx=(b[i].y-z)*1.0/k;double xx1=(b[i].y-z1)*1.0/k1;
				if(x==x1) xx=x1;if(x==x2)xx1=x;if(xx>xx1) swap(xx,xx1);
				if(b[i].x>=xx&&b[i].x<=xx1) return 0;
			}
			else
			if(b[i].y<=y1&&b[i].y>=y2)
			{
				double xx=(b[i].y-z2)*1.0/k2;double xx1=(b[i].y-z1)*1.0/k1;
				if(x1==x2) xx=x1;if(x2==x) xx1=x;if(xx>xx1) swap(xx,xx1);
				if(b[i].x>=xx&&b[i].x<=xx1) return 0;
			}
		}
	}
	else
	{
		for(int i=1;i<=m;i++)
		{
			if(b[i].y<=y&&b[i].y>=y2)
			{
				double xx=(b[i].y-z)*1.0/k;double xx1=(b[i].y-z1)*1.0/k1;
				if(x==x1) xx=x;if(x2==x) xx1=x;if(xx>xx1) swap(xx,xx1);
				if(b[i].x>=xx&&b[i].x<=xx1) return 0;
			}
			else
			if(b[i].y<=y2&&b[i].y>=y1)
			{
				double xx=(b[i].y-z2)*1.0/k2;double xx1=(b[i].y-z)*1.0/k;
				if(x==x1) xx=x;if(x2==x1) xx1=x1;if(xx>xx1) swap(xx,xx1);
				if(b[i].x>=xx&&b[i].x<=xx1) return 0;
			}
		}
	}
	double s,s2,s1;
	s=sqrt(abss(x-x1)*abss(x-x1)+abss(y-y1)*abss(y-y1));
	s1=sqrt(abss(x-x2)*abss(x-x2)+abss(y-y2)*abss(y-y2));
	s2=sqrt(abss(x2-x1)*abss(x2-x1)+abss(y2-y1)*abss(y2-y1));
	double p=(s+s1+s2)*1.0/2;
	double res=sqrt(p*(p-s)*(p-s1)*(p-s2));
	return res;
}
double max1(double x,double y){return(x>y?x:y);}
int main()
{
	//freopen("a.in","r",stdin);
	scanf("%d",&n);
	for(i=1;i<=n;i++)scanf("%d%d",&a[i].x,&a[i].y),a[i].x+=10000,a[i].y+=10000,a[n+i].x=a[i].x,a[n+i].y=a[i].y;
	scanf("%d",&m);
	for(i=1;i<=m;i++)scanf("%d%d",&b[i].x,&b[i].y),b[i].x+=10000,b[i].y+=10000;
	for(i=1;i<=n;i++)
		for(j=1;j<=n;j++)
			if(i!=j) for(int kk=1;kk<=n;kk++)
				if(kk!=i&&kk!=j) 
				{
					t[i][j][kk]=pd(a[i].x,a[i].y,a[j].x,a[j].y,a[kk].x,a[kk].y);
					t[i+n][j][kk]=t[i][j+n][kk]=t[i][j][kk+n]=t[i+n][j+n][kk]=t[i+n][j][kk+n]=t[i][j+n][kk+n]=t[i+n][j+n][kk+n]=t[i][j][kk];
				}
	for(i=1;i<=n;i++)
	{
		for(j=i+1;j<i+n;j++)
		{
			for(int kk=i+1;kk<j;kk++)
			{
				if(t[i][kk][j]!=0)f[i][j]=max1(f[i][j],f[i][kk]+t[i][kk][j]);
			}
			ans2=max1(ans2,f[i][j]);
		}
	}
	if(ans2!=0)printf("%.2lf",ans2);else printf("die");
}

这是AC的

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
struct nup{int x,y;}a[301],b[101];
int i,j,n,m,bz[201];
double t[202][202][202],ans,ans1,ans2,k,l,r,z,f[211][211];
void in(double &k,double &z,int a,int b,int a1,int b1)
{	
	if(b==b1){k=0,z=b;return;}
	a-=a1;b-=b1;k=a*1.0/b;z=a1-k*b1;	
}
int abss(int x){return(x>0?x:-x);}
double pd(int x,int y,int x1,int y1,int x2,int y2)
{
	if(y<y1){swap(x,x1);swap(y,y1);}if(y<y2){swap(x,x2);swap(y,y2);}
	if(x1>x2){swap(x1,x2);swap(y1,y2);}
	double l,k,r,l1,k1,r1,l2,k2,r2,z,z1,z2;//l=kr+z;
	in(k,z,y,x,y1,x1);  in(k1,z1,y,x,y2,x2);  in(k2,z2,y1,x1,y2,x2);
	if(y1>y2)
	{
		for(int i=1;i<=m;i++)
		{
			if(b[i].y<=y&&b[i].y>=y1)
			{
				double xx=(b[i].y-z)*1.0/k;double xx1=(b[i].y-z1)*1.0/k1;
				if(x==x1) xx=x1;if(x==x2)xx1=x;if(xx>xx1) swap(xx,xx1);
				if(b[i].x>xx&&b[i].x<xx1) return 0;
			}
			else
			if(b[i].y<=y1&&b[i].y>=y2)
			{
				double xx=(b[i].y-z2)*1.0/k2;double xx1=(b[i].y-z1)*1.0/k1;
				if(x1==x2) xx=x1;if(x2==x) xx1=x;if(xx>xx1) swap(xx,xx1);
				if(b[i].x>xx&&b[i].x<xx1) return 0;
			}
		}
	}
	else
	{
		for(int i=1;i<=m;i++)
		{
			if(b[i].y<=y&&b[i].y>=y2)
			{
				double xx=(b[i].y-z)*1.0/k;double xx1=(b[i].y-z1)*1.0/k1;
				if(x==x1) xx=x;if(x2==x) xx1=x;if(xx>xx1) swap(xx,xx1);
				if(b[i].x>xx&&b[i].x<xx1) return 0;
			}
			else
			if(b[i].y<=y2&&b[i].y>=y1)
			{
				double xx=(b[i].y-z2)*1.0/k2;double xx1=(b[i].y-z)*1.0/k;
				if(x==x1) xx=x;if(x2==x1) xx1=x1;if(xx>xx1) swap(xx,xx1);
				if(b[i].x>xx&&b[i].x<xx1) return 0;
			}
		}
	}
	double s,s2,s1;
	s=sqrt(abss(x-x1)*abss(x-x1)+abss(y-y1)*abss(y-y1));
	s1=sqrt(abss(x-x2)*abss(x-x2)+abss(y-y2)*abss(y-y2));
	s2=sqrt(abss(x2-x1)*abss(x2-x1)+abss(y2-y1)*abss(y2-y1));
	double p=(s+s1+s2)*1.0/2;
	double res=sqrt(p*(p-s)*(p-s1)*(p-s2));
	return res;
}
double max1(double x,double y){return(x>y?x:y);}
int ppd(int x,int y,int x1,int y1)
{
	for(int i=1;i<=m;i++){if(min(x,x1)<b[i].x&&b[i].x<max(x,x1)&&b[i].y<max(y,y1)&&min(y,y1)<b[i].y) return 0;}
	return 1;
}
int main()
{
	//freopen("a.in","r",stdin);
	scanf("%d",&n);
	for(i=1;i<=n;i++)scanf("%d%d",&a[i].x,&a[i].y),a[i].x+=10000,a[i].y+=10000,a[n+i].x=a[i].x,a[n+i].y=a[i].y;
	scanf("%d",&m);
	for(i=1;i<=m;i++)scanf("%d%d",&b[i].x,&b[i].y),b[i].x+=10000,b[i].y+=10000;
	for(i=1;i<=n;i++)
		for(j=1;j<=n;j++)
			if(i!=j) for(int kk=1;kk<=n;kk++)
				if(kk!=i&&kk!=j) 
				{
					t[i][j][kk]=pd(a[i].x,a[i].y,a[j].x,a[j].y,a[kk].x,a[kk].y);
					t[i+n][j][kk]=t[i][j+n][kk]=t[i][j][kk+n]=t[i+n][j+n][kk]=t[i+n][j][kk+n]=t[i][j+n][kk+n]=t[i+n][j+n][kk+n]=t[i][j][kk];
				}
	for(i=1;i<=n;i++)
	{
		for(j=i+1;j<i+n;j++)
		{
			for(int kk=i+1;kk<j;kk++)
			{
				if(t[i][kk][j]!=0&&ppd(a[i].x,a[i].y,a[kk].x,a[kk].y)==1)
				{
					if(f[i][kk]+t[i][kk][j]>f[i][j])f[i][j]=f[i][kk]+t[i][kk][j];
				}
			}
			ans2=max1(ans2,f[i][j]);
		}
	}
	if(ans2!=0)printf("%.2lf",ans2);else printf("die");
}

这是加判断WA的

posted @ 2021-04-08 21:17  *LZX*  阅读(8)  评论(0编辑  收藏