2007 ACM-ICPC世界总决赛试题分析8-10

8

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
int N,T;
long double pos[305][3];
int Graph[305][305];
int Tri[1005][3];
long double Area[1005];
long double allX[1000005];
long double pool[2][1005];
long double line[1005][2][2];
int Order[2005][2];

int Heap[1005],Size;
int pointer[1005];
long double tmp[2];
long double *cnt,*last;
int s,t;
long double Ans;
long double m1,m2,m3,m4;
int Test=0;
#define Eps 1e-13
#define Equal(a,b) (fabsl((a)-(b))<Eps)
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
#define sqr(a) ((a)*(a))
#define Luck -112901989

long double Cross(long double *pa,long double *pb,long double *pc)
{
	return (pb[0]-pa[0])*(pc[1]-pa[1]) - (pb[1]-pa[1])*(pc[0]-pa[0]);
}

int cmp(const void *a,const void *b)
{
	return (*(long double *)a > *(long double *)b ?1 :-1);
}

int cmp2(const void *a,const void *b)
{
	if(!Equal(line[((int *)a)[0]][((int *)a)[1]][0], line[((int *)b)[0]][((int *)b)[1]][0]))
		return (line[((int *)a)[0]][((int *)a)[1]][0] - line[((int *)b)[0]][((int *)b)[1]][0]?1:-1);
	return (((int *)a)[1] < ((int *)b)[1] ? 1:-1);
}

int Check()
{
	if(!Equal(tmp[0],Luck))
	{
		if(m1>tmp[0])
		{
			m1=tmp[0];
			m3=tmp[1];
		}
		if(m2<tmp[0])
		{
			m2=tmp[0];
			m4=tmp[1];
		}
	}
	return 0;
}

int Inner(long double *pa,long double *pb, long double t)
{
	long double p1,p2;
	p1=pb[0]-t;
	p2=t-pa[0];
	if(p1<-Eps && p2> Eps || p1>Eps && p2<-Eps)
		tmp[0]=Luck;
	else
	{
		tmp[0]=(p1*pa[1] + p2*pb[1])/(p1+p2);
		tmp[1]=(p1*pa[2] + p2*pb[2])/(p1+p2);
	}
	return 0;
}

int Swap(int x)
{
	int i=Heap[x];
	Heap[x]=Heap[(x-1)/2];
	Heap[(x-1)/2]=i;

	pointer[Heap[x]]=x;
	pointer[Heap[(x-1)/2]]=(x-1)/2;
	return 0;
}

int Greater(int a,int b)
{
	long double p1,p2,std;
	std=(Max(line[a][0][0],line[b][0][0]) + Min(line[a][1][0],line[b][1][0]))/2;

	Inner(line[a][0],line[a][1],std);
	p1=tmp[0];
	Inner(line[b][0],line[b][1],std);
	p2=tmp[0];
	if(Equal(p1,Luck) || Equal(p2,Luck))
		while(1);
	return (p1-p2);
}

int modifyUp(int x)
{
	while(x&&Greater(Heap[x],Heap[(x-1)/2]))
	{
		Swap(x);
		x=(x-1)/2;
	}
	return 0;
}

int modifyDown(int x)
{
	int i;
	while(1)
	{
		i=x;
		if(2*x+1<Size && Greater(Heap[2*x+1],Heap[i]))
			i=2*x+1;
		if(2*x+2<Size && Greater(Heap[2*x+2],Heap[i]))
			i=2*x+2;
		if(i==x)
			break;
		Swap(i);
		x=i;
	}
	return 0;
}

int Insert(int x)
{
	Heap[pointer[x]=Size++]=x;
	modifyUp(Size-1);
	return 0;
}

int Delete(int x)
{
	Heap[x]=Heap[--Size];
	pointer[Heap[x]]=x;
	if(x<Size)
	{
		modifyUp(x);
		modifyDown(x);
	}
	return 0;
}

int main()
{
	int i,j,k,l;
	long double *tmp2;
	long double u[3],v[3],vec[3];
	long double a;
	long double t1,t2,b1,b2,c1,c2;
	while(scanf("%d%d",&N,&T)&&(N||T))
	{
		for(i=0;i<N;i++)
			for(j=0;j<3;j++)
			{
				double p;
				scanf("%lf",&p);
				pos[i][j]=p;
			}
		for(i=0;i<N;i++)
			for(j=0;j<N;j++)
				Graph[i][j]=0;
		for(i=0;i<T;i++)
		{
			scanf("%d%d%d",&j,&k,&l);
			j--;
			k--;
			l--;
			if(!Equal(Cross(pos[j],pos[k],pos[l]),0))
			{
				Tri[i][0]=j;
				Tri[i][1]=k;
				Tri[i][2]=l;
				Graph[j][k]=Graph[k][j]=Graph[j][l]=Graph[l][j]=Graph[k][l]=Graph[l][k]=1;
			}
			else
			{
				T--;
				i--;
			}
		}
		s=0;
		for(i=0;i<N;i++)
			for(j=i+1;j<N;j++) if(Graph[i][j])
				for(k=i+1;k<N;k++)
					for(l=k+1;l<N;l++)
						if(Graph[k][l]&&Cross(pos[i],pos[j],pos[k])*Cross(pos[i],pos[j],pos[l])<0
							&&Cross(pos[k],pos[l],pos[i])*Cross(pos[k],pos[l],pos[j])<0)
						{
							t1=pos[l][0]-pos[k][0];
							t2=pos[l][1]-pos[k][1];
							b1=pos[i][0]-pos[j][0];
							b2=pos[j][0]-pos[k][0];
							c1=pos[i][1]-pos[j][1];
							c2=pos[j][1]-pos[k][1];
							a=(t2*b2-t1*c2)/(t1*c1-t2*b1);
							allX[s++]=a*(pos[i][0]-pos[j][0]) + pos[j][0];
						}
		for(i=0;i<N;i++)
		{
			allX[s++]=pos[i][0]-1.2*Eps;
			allX[s++]=pos[i][0]+1.2*Eps;
		}
		qsort(allX,s,sizeof(long double),cmp);
		memset(pool,0,sizeof(pool));
		memset(Area,0,sizeof(Area));
		last=pool[0];
		cnt=pool[1];
		for(i=j=1;i<s;i++)
			if(!Equal(allX[j-1],allX[i]))
				allX[j++]=allX[i];
		s=j;
		for(i=0;i<s;i++)
		{
			a=allX[i];
			k=0;
			l=0;
			for(j=0;j<T;j++)
			{
				m1=1E20;
				m2=-1E20;
				Inner(pos[Tri[j][0]],pos[Tri[j][1]],a);

				Check();
				Inner(pos[Tri[j][1]],pos[Tri[j][2]],a);

				Check();
				Inner(pos[Tri[j][0]],pos[Tri[j][2]],a);

				Check();
				if(m1<m2-Eps)
				{
					line[j][0][0]=m1;
					line[j][0][1]=m3;
					line[j][1][0]=m2;
					line[j][1][1]=m4;
					Order[l][0]=Order[l+1][0]=j;
					Order[l][1]=0;
					Order[l+1][1]=1;
					l+=2;
				}
			}
			qsort(Order,l,sizeof(int)*2,cmp2);
			t=l;
			memset(cnt,0,sizeof(pool[0]));
			Size=0;
			for(j=0;j<t;j++)
			{
				if(Size)
					cnt[Heap[0]]+=line[Order[j][0]][Order[j][1]][0]-line[Order[j-1][0]][Order[j-1][1]][0];
				k=Order[j][0];
				l=Order[j][1];
				if(l==0)
					Insert(k);
				else
					Delete(pointer[k]);
			}
			if(i)
				for(j=0;j<T;j++)
					Area[j]+=(cnt[j]+ last[j])/2*(allX[i]-allX[i-1]);
			tmp2=cnt;
			cnt=last;
			last=tmp2;
		}
		Ans=0;
		for(i=0;i<T;i++)
		{
			for(j=0;j<3;j++)
			{
				u[j]=pos[Tri[i][1]][j]-pos[Tri[i][0]][j];
				v[j]=pos[Tri[i][2]][j]-pos[Tri[i][0]][j];
			}
			vec[2]=1;
			vec[0]=(u[1]*v[2] - v[1]*u[2])/(v[1]*u[0] - u[1]*v[0]);
			vec[1]=(u[0]*v[2] - v[0]*u[2])/(v[0]*u[1] - u[0]*v[1]);
			Ans+=Area[i] * sqrtl(sqr(vec[0]) + sqr(vec[1]) + 1);
		}
		printf("Case %d: %.2llf\n\n",++Test,Ans);
	}
	return 0;
}




9

#include<stdio.h>
#include<math.h>
int n,i,cases;
double tank[11],pipe[11],h0,dh,V,V0,p,k,sum;
double root(double b,double c)
{
	return b/2-sqrt(b*b/4-c);
}

int main()
{
	k=0.097;
	while(scanf("%d",&n)&&n)
	{
		V=0;
		for(i=0;i<n;i++)
		{
			scanf("%lf",&tank[i]);
			if(i)
				V+=tank[i];
		}
		for(i=1;i<n;i++)
			scanf("%lf",&pipe[i]);
		V-=pipe[1];
		p=1;
		sum=pipe[1];
		for(i=1;i<n;i++)
		{
			dh=pipe[i+1]-pipe[i];
			if(i<n-1)
				h0=pipe[i+1] + (p*V/(V-dh)-1)/k;
			if(h0>tank[0]||i==n-1)
			{
				dh=tank[0]-pipe[i];
				sum+=root(dh+V+1/k,dh*V+(1-p)*V/k);
				break;
			}
			sum+=dh;
			p*=V/(V-dh);
			V-=dh;
			h0=pipe[i+1] + (p*V/(V-pipe[i+1])-1)/k;

			if(h0>tank[0])
			{
				sum+=V-V*p/(1+(tank[0]-pipe[i+1])*k);
				break;
			}
			p*=V/(V-pipe[i+1]);
			V-=tank[i];
			V0=tank[i]-pipe[i+1];
			dh=tank[0]-pipe[i+1];
			sum+=pipe[i+1] + root(dh + V0+1/k, dh*V0 + (1-p)*V0/k);
		}
		printf("Case %d: %.3lf\n\n",++cases,sum+tank[0]);
	}
	return 0;
}

10

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int maxn=105;
int cap[maxn][maxn],flow[maxn][maxn];
int n,m;
int x,y;
bool vis[maxn];
int M[maxn];
bool useful[maxn];

bool init()
{
	int i,x,y;
	scanf("%d %d",&n,&m);
	if(n==0&&m==0)
		return false;
	memset(cap,0,sizeof(cap));
	for(i=0;i<m;i++)
	{
		scanf("%d %d",&x,&y);
		cap[x][y]++;
		cap[y][x]++;
	}
	return true;
}

bool dfs(int x)
{
	if(x==0)
		return true;
	if(vis[x])
		return false;
	vis[x]=true;
	for(int i=0;i<=n;i++)
		if(cap[x][i]>flow[x][i]&&dfs(i))
		{
			flow[x][i]++;
			flow[i][x]--;
			return true;
		}
	return false;
}

int maxflow(int sink)
{
	int res=0;
	memset(flow,0,sizeof(flow));
	memset(vis,0,sizeof(vis));
	while(dfs(sink))
	{
		memset(vis,0,sizeof(vis));
		res++;
	}
	return res;
}

void del(int x)
{
	for(int i=0;i<=n;i++)
		cap[i][x]=cap[x][i]=0;
}

int main()
{
	int test=0;
	while(init())
	{
		for(int i=1;i<=n;i++)
			M[i]=maxflow(i);
		memset(useful,0,sizeof(useful));
		for(int i=1;i<=n;i++)
		{
			int m=2147483647;
			for(int j=1;j<=n;j++)
				if(useful[j]==0 && M[j]<m)
					m=M[j];
			for(int j=1;j<=n;j++)
				if(m==M[j])
				{
					useful[j]=true;
					del(j);
				}
				for(int j=1;j<=n;j++)
					if(useful[j]==0)
					{
						M[j]=min(M[j],m+maxflow(j));
					}
		}
		printf("Case %d: %d\n\n",++test,M[1]);
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值