2004 ACM-ICPC世界总决赛试题分析9-10

9

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
char ch;
int C,Tj,Tt,i,j,k;
double d,ans;
int a[30],b[30];

int in()
{
	scanf("%c",&ch);
	while(ch!='C' && ch!='B' && ch!='N')
		scanf("%c",&ch);
	if(ch=='C')
		return 1;
	else if(ch=='B')
		return 2;
	else return 0;
}

double calc_2(double a,double c,double x)
{
	return x/2*sqrt(a*x*x+c) + c/(2*sqrt(a))*log(x*sqrt(a)+sqrt(a*x*x+c));
}

double calc_1(double C)
{
	double A,B,a,b,c;
	if(Tt==Tj)
		B=d/2;
	else
	{
		a=(Tt-Tj)*3;b=2*d*(Tj*3-2-C);c=-d*d*(Tj*3-2-C);
		B=(-b+sqrt(b*b-4*a*c))/(2*a);
		if(B<0||B>d)
			B=(-b-sqrt(b*b-4*a*c))/(2*a);
	}
	A=(Tj*3-2-C)/(B*B);
	return calc_2(4*A*A,1,B)+calc_2(4*A*A,1,d-B);
}

int main()
{
	C=0;
	while(1)
	{
		scanf("%d %d %lf",&Tj,&Tt,&d);
		if(Tj==0&&Tt==0&&d<1e-6)
			break;
		memset(a,0,sizeof(a));
		memset(b,0,sizeof(b));
		for(i=1;i<=Tj;i++)
			a[i]=in();
		for(i=1;i<=Tt;i++)
			b[i]=in();
		ans=-1;
		for(i=1;i<Tt&&i<Tj;i++)
		{
			if(i>1)
				if((a[i]!=1&&b[i]!=1)||(a[i-1]!=2&&b[i-1]!=2))
				{
					ans=calc_1(i*3-2-0.5+1);
					if(C) 
						printf("\n");
					printf("Case %d: %.3lf\n",++C,ans);
					break;
				}
				if((a[i]!=1 && b[i]!=1) || (a[i]!=2&&b[i]!=2))
				{
					if(C)
						printf("\n");
					ans=calc_1(i*3-2+1);
					printf("Case %d: %.3lf\n",++C,ans);
					break;
				}
				if((a[i+1]!=1&&b[i+1]!=1) || (a[i]!=2&&b[i]!=2))
				{
					if(C)
						printf("\n");
					ans=calc_1(i*3-2+0.5+1);
					printf("Case %d: %.3lf\n",++C,ans);
					break;
				}
		}
		if(ans<0)
		{
			if(C)
				printf("\n");
			printf("Case %d: impossible\n",++C);
		}
	}
	return 0;
}

10

#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<stdlib.h>
#include<math.h>
using namespace std;
const double eps=1e-5;
struct coor
{
	double x,y;
};
double r;
int C,NP,NC,m,i,j,k,ok;
int covers[100],ans[10],cov[100],Tc[100];
coor A,B;
coor P[100];
coor operator -(coor a,coor b)
{
	a.x-=b.x;
	a.y-=b.y;
	return a;
}

bool cmp(coor a,coor b)
{
	return a.y>b.y+eps || (a.y>b.y-eps && a.x>b.x);
}

double len(coor a)
{
	return sqrt(a.x*a.x + a.y*a.y);
}

bool cross(coor A,coor B,coor C,coor &O)
{
	double A1,B1,C1,A2,B2,C2,tmp;
	A1=B.x-A.x;
	B1=B.y-A.y;
	C1=(A.y*A.y-B.y*B.y+A.x*A.x-B.x*B.x)/2.0;
	A2=C.x-A.x;
	B2=C.y-A.y;
	C2=(A.y*A.y-C.y*C.y+A.x*A.x-C.x*C.x)/2.0;
	tmp=B1*A2-B2*A1;
	if(fabs(tmp)<eps)
		return false;
	O.y=(C2*A1-C1*A2)/tmp;
	O.x=(C1*B2-C2*B1)/tmp;
	return true;
}

bool check()
{
	int i;
	for(i=0;i<NP;i++)
	{
		if(cov[i]&&!Tc[i])
			return false;
		if(!cov[i]&&Tc[i])
			return true;
	}
	return true;
}

void work(coor A,coor B,coor C)
{
	coor O;
	double Tr;
	int i,in,on;
	if(!cross(A,B,C,O))
		return ;
	Tr=len(A-O);
	in=0;on=0;
	for(i=0;i<NP;i++)
		if(len(O-P[i])<Tr-eps)
			in++;
		else if(len(O-P[i])<Tr+eps)
			on++;
	if(in>m || in+on<m)
		return;
	on=m-in;
	for(i=0;i<NP;i++)
		if(len(O-P[i])<Tr-eps)
			Tc[i]=1;
		else if(len(O-P[i])<Tr+eps && on)
		{
			Tc[i]=1;on--;
		}
		else
			Tc[i]=0;
	if(r<0||Tr<r-eps||(Tr<r+eps && check()))
	{
		r=Tr;
		for(i=0;i<NP;i++)
			cov[i]=Tc[i];
	}
}

int main()
{
	while(scanf("%d%d",&NP,&NC)&&NP)
	{
		for(i=0;i<NP;i++)
			scanf("%lf %lf",&P[i].x,&P[i].y);
		sort(P,P+NP,cmp);
		memset(covers,0,sizeof(covers));
		ok=1;
		for(i=0;i<NC;i++)
		{
			scanf("%d %lf %lf %lf %lf",&m,&A.x,&A.y,&B.x,&B.y);
			r=-1;
			for(j=0;j<NP;j++)
				work(A,B,P[j]);
			for(j=0;j<NP;j++)
				covers[j]+=cov[j];
			if(r<0)
				ok=0;
		}
		memset(ans,0,sizeof(ans));
		for(i=0;i<NP;i++)
			ans[covers[i]]++;
		printf("Trial %d:  ",++C);
		if(ok)
			for(i=0;i<=NC;i++)
				printf("%d  ",ans[i]);
		else
			printf("Impossible");
		printf("\n\n");
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值