2009 ACM-ICPC世界总决赛试题分析4-7

4

#include<stdio.h>
#include<math.h>
#include<string.h>
#include<iostream>
using namespace std;
int rad[11];
double que[11],pi=acos(double(-1.0));
bool temp[11];

bool check(double p1,double p2,double p3)
{
	if(p1>p2)
		swap(p1,p2);
	if(p1>p3)
		swap(p1,p3);
	if(p2>p3)
		swap(p2,p3);
	if(p1<=0)
		return false;
	if(p1+p2<=p3)
		return false;
	return true;
}

bool dfs(int o,double key)
{
	int i,j;
	if(o>4)
	{
		if(que[1]<que[2]||que[1]<que[3]||que[1]<que[4])
			return false;
		double s=0,tmp,p1,p2,p3,maxn,f[11];
		for(i=1;i<=5;i++)
			f[i]=0;
		que[5]=que[1];
		for(i=2;i<=5;i++)
		{
			for(j=1;j<i;j++)
				if(j!=1||i!=5)
				{
					p1=key-que[i];
					p2=key-que[j];
					p3=que[i]+que[j];
					if(check(p1,p2,p3)==false)
						return false;
					tmp=(p1*p1+p2*p2-p3*p3)/2/p1/p2;
					tmp=acos(tmp);
					if(tmp+f[j]>f[i])
						f[i]=tmp+f[j];
				}
		}
		if(f[5]>2*pi)
		{
			return false;
		}
		return true;
	}
	for(i=1;i<=4;i++) 
		if(temp[i]==false)
		{
			temp[i]=true;
			que[o]=rad[i];
			bool tmp=dfs(o+1,key);
			if(tmp==true)
				return true;
			temp[i]=false;
		}
	return false;
}

int main()
{
	double l,r,mid;
	bool ok;
	int t=0;
	while(scanf("%d",&rad[1])&&rad[1]!=0)
	{
		t++;
		scanf("%d%d%d",&rad[2],&rad[3],&rad[4]);
		l=0;r=100000;
		while(r-l>0.1)
		{
			mid=(l+r)/2;
			memset(temp,false,sizeof(temp));
			ok=dfs(1,mid);
			if(ok)
				r=mid;
			else
				l=mid;
		}
		printf("Case %d: %.0lf\n",t,r);
	}
	return 0;
}

5

#include<stdio.h>
#include<string.h>
#include<stdlib.h>


struct dat_edge
{
	int aim,last,cost,site,dire;	
}edge[100001];

int f[50001],ans[50001],coun_ans,coun0[50001],coun1[50001],pl[50001],len_edge,n,m;
bool bi[50001];

void insert_edge(int x,int y,int s,int w,int p)
{
	len_edge++;
	edge[len_edge].aim=y;
	edge[len_edge].cost=s;
	edge[len_edge].site=w;
	edge[len_edge].dire=p;
	edge[len_edge].last=pl[x];
	pl[x]=len_edge;
}

void solve()
{
	static int o,w,que[50001],p,s,poi;
	o=1;w=0;que[1]=1;
	memset(f,0,sizeof(f));
	memset(bi,false,sizeof(bi));
	while(w<o)
	{
		w++;
		p=pl[que[w]];
		while(p!=-1)
		{
			if(edge[p].dire!=1)
			{
				p=edge[p].last;
				continue;
			}
			poi=edge[p].aim;
			if(f[que[w]]+edge[p].cost>f[poi])
				f[poi]=f[que[w]]+edge[p].cost;
			coun1[poi]--;
			if(coun1[poi]==0)
				que[++o]=poi;
			p=edge[p].last;
		}
		p=pl[que[w]];
		while(p!=-1)
		{
			if(edge[p].dire!=0)
			{
				p=edge[p].last;
				continue;
			}
			if(bi[edge[p].aim]==true)
			{
				bi[que[w]]=true;
				break;
			}
			s=f[edge[p].aim]+edge[p].cost;
			if(s==f[que[w]])
			{
				p=edge[p].last;
				continue;
			}
			bi[que[w]]=true;
			break;
		}
	}
}

bool re_solve()
{
	static int o,w,que[50001],p,s,poi,i,toll[50001];
	for(i=1;i<=n;i++)
		toll[i]=-1;
	o=1;w=0;que[1]=n;
	while(w<o)
	{
		w++;
		if(toll[que[w]]<0)
			toll[que[w]]=0;
		p=pl[que[w]];
		while(p!=-1)
		{
			if(edge[p].dire==1)
			{
				p=edge[p].last;
				continue;
			}
			poi=edge[p].aim;
			coun0[poi]--;
			if(coun0[poi]==0)
				que[++o]=poi;
			s=f[que[w]]-f[poi]-edge[p].cost+toll[que[w]];
			if(bi[poi]==false)
			{
				ans[edge[p].site]+=s;
			}
			else
			{
				if(toll[poi]!=-1&&toll[poi]!=s)
					return false;
				toll[poi]=s;
			}
			p=edge[p].last;
		}
	}
	return true;
}

int main()
{
	int t=0,i,a,b,c;
	bool ok;
	while(scanf("%d%d",&n,&m)&&n+m!=0)
	{
		t++;
		memset(coun1,0,sizeof(coun1));
		memset(coun0,0,sizeof(coun0));
		len_edge=-1;
		for(i=1;i<=n;i++)
			pl[i]=-1;
		for(i=1;i<=m;i++)
		{
			scanf("%d%d%d",&a,&b,&c);
			coun1[b]++;
			coun0[a]++;
			insert_edge(a,b,c,i,1);
			insert_edge(b,a,c,i,0);
		}
		coun_ans=0;
		memset(ans,0,sizeof(ans));
		memset(bi,false,sizeof(bi));
		solve();
		ok=re_solve();
		if(!ok)
			printf("Case %d: No solution\n",t);
		else
		{
			for(i=1;i<=m;i++)
				if(ans[i]!=0)
					coun_ans++;
			printf("Case %d: %d %d\n",t,coun_ans,f[n]);
			for(i=1;i<=m;i++)
				if(ans[i]!=0)
					printf("%d %d\n",i,ans[i]);
		}
	}
	return 0;
}

6

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<algorithm>
using namespace std;
struct node
{
	int x,y;
}tmp[50];
int x[50],y[50],z[50];
int n,M;
double f[1200];
double const pi=acos(-1.0);

int cmp(node a,node b)
{
	if(a.x!=b.x)
		return a.x<b.x;
	return a.y<b.y;
}

int cross(int i,int j,int k)
{
	int x1=tmp[j].x-tmp[i].x;
	int y1=tmp[j].y-tmp[i].y;
	int x2=tmp[k].x-tmp[j].x;
	int y2=tmp[k].y-tmp[j].y;
	return x1*y2-x2*y1;
}

double sqr(int x)
{
	return x*x;
}

double dist(int i,int j)
{
	return sqrt(sqr(tmp[i].x-tmp[j].x) + sqr(tmp[i].y-tmp[j].y));
}

double get(int opt)
{
	int m=0;
	for(int i=0;i<n;i++)
		if(opt&(1<<i))
		{
			tmp[++m].x=x[i];
			tmp[m].y=y[i];
		}
	if(m==1)
		return pi*M*2;
	sort(tmp+1,tmp+m+1,cmp);
	int h=1,t=1;
	z[1]=1;
	for(int i=2;i<=m;i++)
	{
		while(h<t&&(cross(z[t-1],z[t],i)<0))
			t--;
		z[++t]=i;
	}
	for(int i=m-1;i;i--)
	{
		while(h<t&&(cross(z[t-1],z[t],i)<0))
			t--;
		z[++t]=i;
	}
	double ans=0;
	for(int i=1;i<t;i++)
		ans+=dist(z[i],z[i+1]);
	return ans+pi*M*2;
}

int main()
{
	int test=0;
	while(scanf("%d %d\n",&n,&M)&&n)
	{
		for(int i=0;i<n;i++)
			scanf("%d %d\n",&x[i],&y[i]);
		for(int i=1;i<1<<n;i++)
			f[i]=get(i);
		for(int i=1;i<1<<n;i++)
			for(int j=i;j;j=(j-1)&i)
				if((i&j)==j)
					f[i]=min(f[i],f[i-j]+f[j]);
		printf("Case %d: length = %.2lf\n",++test,f[(1<<n)-1]);
	}
	return 0;
}

7

#include<stdio.h>
#include<string.h>
#include<string>
#include<stdlib.h>
using namespace std;
struct dat_que
{
	int dir,poi;
}que[9];
struct dat_card
{
	char col;
	int dig;
}card[30];
string order[30];
int inf=100000,n;

int calc_hold_card(int ax_hold,int bi_hold)
{
	int s=0;
	if(ax_hold!=-1)
	{
		if(card[ax_hold].col=='R')
			s+=card[ax_hold].dig;
		else
			s-=card[ax_hold].dig;
	}
	if(bi_hold!=-1)
	{
		if(card[bi_hold].col=='B')
			s-=card[bi_hold].dig;
		else
			s+=card[bi_hold].dig;
	}
	return s;
}

void update(int &rec,int s)
{
	if(s>rec)
		rec=s;
}

int calc_digit(int pha,int p1,int p2,int p3)
{
	int counr,counb,dig;
	counr=counb=dig=0;
	dig=card[p1].dig+card[p2].dig+card[p3].dig;
	if(card[p1].col=='B')
		counb++;
	else
		counr++;
	if(card[p2].col=='B')
		counb++;
	else
		counr++;
	if(card[p3].col=='B')
		counb++;
	else
		counr++;
	if(counr>1)
	{
		if(order[pha]=="Axel")
			return dig;
		else
			return -dig;
	}
	else
	{
		if(order[pha]=="Birgit")
			return dig;
		else
			return -dig;
	}
}

int dfs(int pha,int ax_hold,int bi_hold,int maxn)
{
	if(pha>2*n)
	{
		int s=calc_hold_card(ax_hold,bi_hold);
		if(order[pha]=="Axel")
			return s;
		else
			return -s;
	}
	int rec,i,calc,tmp;
	dat_que temp_que[9];
	rec=-inf;
	memcpy(temp_que,que,sizeof(que));
	tmp=inf;
	if(order[pha]=="Axel"&&ax_hold==-1)
	{
		tmp=dfs(pha+1,pha,bi_hold,rec);
	}
	else if(order[pha]=="Birgit"&&bi_hold==-1)
	{
		tmp=dfs(pha+1,ax_hold,pha,rec);
	}
	update(rec,-tmp);
	if(maxn>=-rec)
		return rec;
	for(i=2;i<=6;i++)
		if(que[i].dir==-1&&que[i+1].dir==1)
		{
			calc=calc_digit(pha,que[i].poi,que[i+1].poi,pha);
			que[i].dir=que[i+1].dir=0;
			que[i].poi=pha;que[i+1].poi=-1;
			tmp=dfs(pha+1,ax_hold,bi_hold,rec-calc);
			update(rec,calc-tmp);
			que[i]=temp_que[i];que[i+1]=temp_que[i+1];
			if(maxn>=-rec)
				return rec;
			if(order[pha]=="Axel"&&ax_hold!=-1)
			{
				calc=calc_digit(pha,que[i].poi,que[i+1].poi,ax_hold);
				que[i].dir=que[i+1].dir=0;
				que[i].poi=ax_hold;que[i+1].poi=-1;
				tmp=dfs(pha+1,pha,bi_hold,rec-calc);
				update(rec,calc-tmp);
			}
			else if(order[pha]=="Birgit"&&bi_hold!=-1)
			{
				calc=calc_digit(pha,que[i].poi,que[i+1].poi,bi_hold);
				que[i].dir=que[i+1].dir=0;
				que[i].poi=bi_hold;que[i+1].poi=-1;
				tmp=dfs(pha+1,ax_hold,pha,rec-calc);
				update(rec,calc-tmp);
			}
			que[i]=temp_que[i];
			que[i+1]=temp_que[i+1];
			if(maxn>=-rec)
				return rec;
		}
	for(i=2;i<=6;i++)
		if(que[i].dir==0&&que[i+1].dir==0&&que[i].poi!=-1&&que[i+1].poi==-1)
		{
			if(order[pha]=="Axel"&&ax_hold!=-1)
			{
				calc=calc_digit(pha,que[i].poi,ax_hold,pha);
				que[i].dir=1;que[i+1].dir=-1;
				que[i].poi=pha;que[i+1].poi=ax_hold;
				tmp=dfs(pha+1,-1,bi_hold,rec-calc);
				tmp=dfs(pha+1,ax_hold,pha,rec);
				update(rec,calc-tmp);
				que[i]=temp_que[i];
				que[i+1]=temp_que[i+1];
				if(maxn>=-rec)
					return rec;
				calc=calc_digit(pha,que[i].poi,ax_hold,pha);
				que[i].dir=1;que[i+1].dir=-1;
				que[i].poi=ax_hold;que[i+1].poi=pha;
				tmp=dfs(pha+1,-1,bi_hold,rec-calc);
				update(rec,calc-tmp);
				que[i]=temp_que[i];
				que[i+1]=temp_que[i+1];
				if(maxn>=-rec)
					return rec;
			}
			else if(order[pha]=="Birgit"&&bi_hold!=-1)
			{
				calc=calc_digit(pha,que[i].poi,bi_hold,pha);
				que[i].dir=1;que[i+1].dir=-1;
				que[i].poi=pha;que[i+1].poi=bi_hold;
				tmp=dfs(pha+1,ax_hold,-1,rec-calc);
				update(rec,calc-tmp);
				que[i]=temp_que[i];
				que[i+1]=temp_que[i+1];
				if(maxn>=-rec)
					return rec;
				calc=calc_digit(pha,que[i].poi,bi_hold,pha);
				que[i].dir=1;que[i+1].dir=-1;
				que[i].poi=bi_hold;que[i+1].poi=pha;
				tmp=dfs(pha+1,ax_hold,-1,rec-calc);
				update(rec,calc-tmp);
				que[i]=temp_que[i];
				que[i+1]=temp_que[i+1];
				if(maxn>=-rec)
					return rec;
			}
		}
	return rec;
}

int main()
{
	int t=0,i,ans,len;
	char name[10];
	while(scanf("%s",&name)&&string(name)!="End")
	{
		t++;
		scanf("%d",&n);
		for(i=1;i<=2*n;i++)
		{
			char z[10];
			scanf("%s",&z);
			len=strlen(z);
			if(len==2)
			{
				card[i].col=z[1];
				card[i].dig=z[0]-'0';
			}
			else
			{
				card[i].col=z[2];
				card[i].dig=(z[0]-'0')*10 + (z[1]-'0');
			}
		}
		for(i=1;i<=8;i++)
		{
			que[i].poi=i;
			if(i%2==1)
				que[i].dir=1;
			else
				que[i].dir=-1;
		}
		if(card[1].col='B')
			order[9]="Birgit";
		else
			order[9]="Axel";
		for(i=10;i<=2*n+1;i++)
		{
			if(order[i-1]=="Birgit")
				order[i]="Axel";
			else
				order[i]="Brigit";
		}
		ans=dfs(9,-1,-1,-inf);
		if(order[9]!=string(name))
			ans*=-1;
		if(ans==0)
		{
			printf("Case %d: Axel and Birgit tie\n",t);
		}
		else if(ans>0)
		{
			printf("Case %d: %s wins %d\n",t,name,ans);
		}
		else
		{
			printf("Case %d: %s loses %d\n",t,name,-ans);
		}
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值