1157. 【GDOI2004】可憐的綿羊 (Standard IO)

1157. 【GDOI2004】可憐的綿羊 (Standard IO)

因爲這道題的數據特別小(n<=100),因此咱們能夠考慮較爲暴力的作法。
首先擴倍,因爲是按逆時針順序給出各個樹樁所在的座標,因此。。。是爲了後面的方便。。無所謂了。
咱們先預處理t[i][j][k]表示以i,j,k爲頂點的三角形是否存在即(三角形裏不存在毒藥),若存在t[i][j][k]=面積,若不存在爲0;
咱們先考慮如何求t;咱們首先能夠對於任何一個三角形能夠把其分爲如下兩種c++

分別記錄一下三條線的y=kx+b;而後暴力掃一遍m,而後分類討論(以第二高的點劃分而後,分上下討論)看一下三角形裏有沒有毒,如有return0;else return S=sqrt(q(q-a)(q-b)(q-c)); 。。。。。大家有更好的方法就。。。別打擊我。
這裏理論來講應該是O(n^4)的,可能數據水了,或跑不滿剪了許多。spa

而後設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]}不過這裏要特判一下,毒藥剛好在兩個三角形邊界上的狀況。例如:code

#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的blog

#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的string

相關文章
相關標籤/搜索