2008 ACM-ICPC世界总决赛试题分析8-11

8

#include<stdio.h>
#include<time.h>
#include<string.h>
#include<utility>
#include<algorithm>
#include<set>
#include<math.h>
#include<stdlib.h>
#include<iostream>
#define X first
#define Y second
using namespace std;
const int MAXN=300110;
const int MAXM=900110;
const long double PI=3.1415926535898;
const long double EPS=1e-9;
typedef pair<long double,long double> Tpoint;
Tpoint a[MAXM][3];
int n;
pair<int,int> b[MAXM];
int f[MAXN],d[MAXN];
long double tmp;

struct Tnode
{
	long double p,v;
	int t,pos;
	inline bool operator==(const Tnode &x)
	{
		return (x.t==t) && (x.pos==pos);
	}
	inline long double value()
	{
		return (p+v*tmp);
	}
};

inline bool operator < (const Tnode &y,const Tnode &x)
{
	return (y.p+y.v*tmp<x.p+x.v*tmp-EPS)||(((fabs(y.p+y.v*tmp-x.p-x.v*tmp)<EPS)&&(y.t<x.t)));
}

inline bool equal(long double x,long double y)
{
	return fabs(x-y)<EPS;

}

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

inline bool cmp2(const pair<int,int>&x,const pair<int,int>&y)
{
	return a[x.X][x.Y].X<a[y.X][y.Y].X;
}

inline void rorate(Tpoint &a,long double alpha)
{
	long double x,y;
	x=a.X*cos(alpha) - a.Y*sin(alpha);
	y=a.X*sin(alpha) + a.Y*cos(alpha);
	a.X=x;
	a.Y=y;
}

int getf(int p)
{
	if(p==-1)
		return 1;
	else if(d[p]!=-1)
		return d[p];
	else
		return d[p]=getf(f[p])+1;
}


void init()
{
	int i,j,k,l;
	int tx,ty;
	for(i=0;i<n;++i)
		for(j=0;j<3;++j)
		{
			scanf("%d %d",&tx,&ty);
			a[i][j].X=tx;
			a[i][j].Y=ty;
		}
	long double alpha=rand()%30000/30000.0*PI;
	for(i=0;i<n;++i)
	{
		for(j=0;j<3;++j)
			rorate(a[i][j],alpha);
		qsort(a[i],3,sizeof(long double)*2,cmp);
		b[3*i].X=b[3*i+1].X=b[3*i+2].X=i;
		b[3*i].Y=0;
		b[3*i+1].Y=1;
		b[3*i+2].Y=2;
	}
	sort(b,b+3*n,cmp2);
}

void solve()
{
	int i,j,k,l;
	Tnode t1,t2,t3;
	long double td;
	set<Tnode> t;
	set<Tnode> :: iterator i1,i2,i3;
	t.clear();
	bool ok=1;
	memset(f,0xff,sizeof(f));
	for(i=0;ok&&(i<3*n);++i)
	{
		j=b[i].X;
		k=b[i].Y;
		tmp=a[j][k].X;
		if(k==0)
		{
			t1.v=(a[j][1].Y - a[j][0].Y)/(a[j][1].X - a[j][0].X);
			t1.p=a[j][0].Y-a[j][0].X*t1.v;
			t2.v=(a[j][2].Y - a[j][0].Y)/(a[j][2].X - a[j][0].X);
			t2.p=a[j][0].Y-a[j][0].X*t2.v;
			t1.pos=t2.pos=j;
			if(t1.v>t2.v)
			{
				t3=t1;
				t1=t2;
				t2=t3;
			}
			t1.t=0;
			t2.t=1;
			i1=t.lower_bound(t1);
			t3=(*i1);
			if((i1!=t.end())&&equal(t3.value(),t1.value()))
			{
				ok=false;
				break;
			}
			t.insert(t1);
			t.insert(t2);
			i1=t.find(t1);
			if(i1==t.end())
			{
				ok=false;
				break;
			}
			if(i1!=t.begin())
			{
				i1--;
				if(i1->t==1)
					f[j]=f[i1->pos];
				else
					f[j]=i1->pos;
			}
		}
		else if(k==1)
		{
			if((a[j][1].Y-a[j][0].Y)/(a[j][1].X-a[j][0].X)<(a[j][2].Y-a[j][0].Y)/(a[j][2].X-a[j][0].X))
				l=0;
			else
				l=1;
			t1.v=(a[j][1].Y - a[j][0].Y)/(a[j][1].X - a[j][0].X);
			t1.p=a[j][0].Y-a[j][0].X*t1.v;
			t1.pos=j;
			t1.t=l;
			td=t1.value();
			i1=t.find(t1);
			if(i1==t.end())
			{
				ok=false;
				break;
			}
			if(i1!=t.begin())
			{
				i1--;
				t3=(*i1);
				if(td<=t3.value()+EPS)
				{
					ok=false;
					break;
				}
				i1++;
			}
			i1++;
			if(i1!=t.end())
			{
				t3=(*i1);
				if(td>=t3.value()-EPS)
				{
					ok=false;
					break;
				}
			}
			t.erase(t1);
			t1.v=(a[j][2].Y - a[j][1].Y)/(a[j][2].X - a[j][1].X);
			t1.p=a[j][1].Y-a[j][1].X*t1.v;
			t.insert(t1);
		}
		else
		{
			if((a[j][1].Y-a[j][0].Y)/(a[j][1].X-a[j][0].X)>=(a[j][2].Y-a[j][0].Y)/(a[j][2].X-a[j][0].X))
			{
				t1.v=(a[j][2].Y - a[j][0].Y)/(a[j][2].X - a[j][0].X);
				t1.p=a[j][0].Y-a[j][0].X*t1.v;
			}
			else
			{
				t1.v=(a[j][2].Y - a[j][1].Y)/(a[j][2].X - a[j][1].X);
				t1.p=a[j][1].Y-a[j][1].X*t1.v;
			}
			t1.pos=j;
			t1.t=0;
			i2=t.find(t1);
			i1=i2++;
			if((i1==t.end())||(i2==t.end())||(i2->pos!=j)||(i2->t!=1))
			{
				ok=false;
				break;
			}
			td=t1.value();
			i3=i2++;
			t.erase(i3);
			if(i2!=t.end())
			{
				t3=(*i2);
				if(t3.value()<=EPS+td)
				{
					ok=false;
					break;
				}
			}
			i3=i1--;
			if(i3!=t.begin())
			{
				t3=(*i1);
				if(t3.value()>=td-EPS)
				{
					ok=false;
					break;
				}
			}
			t.erase(i3);
		}
	}
	if(!ok)
	{
		printf("ERROR\n");
		return;
	}
	int ans=1;
	memset(d,0xff,sizeof(d));
	for(i=0;i<n;++i)
		ans=max(ans,getf(i));
	printf("%d shades\n",ans);
}

int main()
{
	srand(time(NULL));
	int CASE=0;
	while((scanf("%d",&n)!=EOF)&&(n!=-1))
	{
		init();
		printf("Case %d: ",++CASE);
		solve();
	}
	return 0;
}

9

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
using namespace std;
struct info
{
	int P;
	int next[26];
};
const int MaxN=25;
const int MaxM=10;
const int MaxL=10;
const int MaxOut=42;
char word[MaxM][MaxL+1],list[MaxOut+1][MaxN+1];
long long ans,list_num;
int cases,n,m,c,sum;
info prefix[MaxM*MaxL+1];
long long f[MaxN+1][1<<MaxM][MaxM*MaxL+1];
int tmp[MaxOut+1];
void refresh(int x)
{
	memset(prefix[x].next,0,sizeof(prefix[x].next));
	prefix[x].P=0;
}

int check(int s)
{
	int i,now;
	now=1;
	for(i=s;i<=tmp[0];i++)
		if(prefix[now].next[tmp[i]]>0)
			now=prefix[now].next[tmp[i]];
		else
			return 0;
	return now;
}

void work(int x)
{
	int i,j,k;
	tmp[0]++;
	for(i=0;i<26;i++)
		if(prefix[x].next[i]>0)
		{
			tmp[tmp[0]]=i;
			work(prefix[x].next[i]);
		}
		else
		{
			tmp[tmp[0]]=i;
			for(j=1;j<=tmp[0]+1;j++)
			{
				k=check(j);
				if(k!=0)
				{
					prefix[x].next[i]=k;
					break;
				}
			}
		}
		tmp[0]--;
}

bool cmp(int x,int y)
{
	return (strcmp(list[x],list[y])<0);
}

void rework(int Len,int l,int now)
{
	int i,L,k;
	if(f[Len][l][now]==0)
		return;
	if(Len==0)
	{
		list_num++;
		for(i=0;i<n;i++)
			list[list_num][i]=tmp[i+1]+'a';
		list[list_num][n]='\0';
		return;
	}
	for(L=0;L<26;L++)
		for(i=1;i<=sum;i++)
			if(prefix[i].next[L]==now)
			{
				tmp[Len]=L;
				rework(Len-1,l,i);
				if(prefix[now].P)
					rework(Len-1,l-(1<<(prefix[now].P-1)),i);
			}
}


bool init()
{
	int i,j,k,now,l,t;
	scanf("%d %d",&n,&m);
	if(n==0)
		return true;
	for(i=1;i<=m;i++)
		scanf("%s",word[i]);
	for(i=m;i>=1;i--)
		for(j=1;j<=m;j++)
			if(strlen(word[j])>=strlen(word[i])&&i!=j)
			{
				for(k=0;k<=strlen(word[j]-strlen(word[i]));k++)
				{
					t=0;
					for(l=0;word[i][l]!='\0';l++)
						if(word[i][l]!=word[j][l+k])
							t=1;
					if(t==0)
						break;
				}
				if(t==0)
				{
					for(k=i+1;k<=m;k++)
					{
						for(l=0;'a'<=word[k][l]&&word[k][l]<='z';l++)
							word[k-1][l]=word[k][l];
						word[k-1][l]='\0';
					}
					m--;
					break;
				}
			}
			sum=1;refresh(1);
			for(i=1;i<=m;i++)
			{
				now=1;
				for(j=0;'a'<=word[i][j]&&word[i][j]<='z';j++)
				{
					if(prefix[now].next[word[i][j]-'a']==0)
					{
						sum++;
						refresh(sum);
						prefix[now].next[word[i][j]-'a']=sum;
					}
					now=prefix[now].next[word[i][j]-'a'];
				}
				prefix[now].P=i;
			}
		tmp[0]=0;
		work(1);
		memset(f,0,sizeof(f));
		f[0][0][1]=1;
		return false;
}

void DP()
{
	int i,j,k,c;
	for(i=0;i<n;i++)
		for(j=0;j<(1<<m);j++)
			for(k=1;k<=sum;k++)
				if(f[i][j][k])
					for(c=0;c<26;c++)
						f[i+1][j|(1<<(prefix[prefix[k].next[c]].P-1))][prefix[k].next[c]]+=f[i][j][k];
}

void write()
{
	int i;
	ans=0;
	for(i=1;i<=sum;i++)
		ans+=f[n][(1<<m)-1][i];
	printf("Case %d: %lld suspects\n",++cases,ans);
	if(ans<=MaxOut)
	{
		list_num=0;
		for(i=1;i<=sum;i++)
			if(f[n][(1<<m)-1][i]>0)
				rework(n,(1<<m)-1,i);
		for(i=1;i<=ans;i++)
			tmp[i]=i;
		sort(tmp+1,tmp+ans+1,cmp);
		for(i=1;i<=ans;i++)
			printf("%s\n",list[tmp[i]]);
	}
}

int main()
{
	while(1)
	{
		if(init())
			break;
		DP();
		write();
	}
	return 0;
}

10

#include<stdio.h>
#include<math.h>
#include<algorithm>
using namespace std;
const int maxn=111;
const int maxpoints=11111;
const double eps=1e-9;
int n,i,j,points,id[maxpoints],cases;
double x[maxn],h[maxn],b[maxn],point[maxpoints],left,right,mid,top,side,k,height,len;

void addpoints(double z)
{
	point[points]=z;
	id[points]=points;
	points++;
}

void cross(double xa,double xb,double yb,double xc,double xd,double yd)
{
	double va,vc,t;
	va=(xb-xa)/yb;vc=(xd-xc)/yd;
	if(fabs(va-vc)<1e-9)
		return;
	t=(xc-xa)/(va-vc);
	if(t>0&&t<yb&&t>yd)
		addpoints(xa+va*t);
}

bool cmp(int i,int j)
{
	return point[i]<point[j];
}

int main()
{
	while(scanf("%d",&n)&&n)
	{
		points=0;
		for(i=0;i<n;i++)
		{
			scanf("%lf%lf%lf",&x[i],&h[i],&b[i]);
			b[i]/=2;
			addpoints(x[i]-b[i]);
			addpoints(x[i]);
			addpoints(x[i]+b[i]);
			for(j=0;j<i;j++)
			{
				cross(x[i]-b[i],x[i],h[i],x[j]-b[j],x[j],h[j]);
				cross(x[i]+b[i],x[i],h[i],x[j]-b[j],x[j],h[j]);
				cross(x[i]-b[i],x[i],h[i],x[j]+b[j],x[j],h[j]);
				cross(x[i]+b[i],x[i],h[i],x[j]+b[j],x[j],h[j]);
			}
		}
		sort(id,id+points,cmp);
		len=0;
		for(i=1;i<points;i++)
		{
			left=point[id[i-1]];
			right=point[id[i]];
			mid=(left+right)/2;
			if(right-left>eps)
			{
				top=-2;
				for(j=0;j<n;j++)
				{
					side=x[j]-b[j];
					if(side<mid&&x[j]>mid)
					{
						height=h[j]*(mid-side)/b[j];
						if(height>top)
						{
							top=height;
							k=h[j]/b[j];
						}
					}
					side=x[j]+b[j];
					if(x[j]<mid&&side>mid)
					{
						height=h[j]*(side-mid)/b[j];
						if(height>top)
						{
							top=height;
							k=h[j]/b[j];
						}
					}
				}
				if(top>-1)
					len+=(right-left)*sqrt(1+k*k);
			}
		}
		printf("Case %d: %d\n\n",++cases,((int)((len+0.5)*10))/10);
	}
	return 0;
}


11

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
struct info
{
	int x,y,kind,T;
};

const int MaxN=100;
const int MaxM=100;
const int change[4][2]={1,0, 0,1, -1,0, 0,-1};
int n,m,i,j,k,sum,cases;
info st,ed,s;
info heap[5*MaxN*MaxM];
int position[MaxN+1][MaxM+1][5];
int Time[MaxN+1][MaxM+1][4];

void up(int x)
{
	int k;
	while(x>1&&heap[x].T<heap[x/2].T)
	{
		k=x/2;
		heap[0]=heap[k];
		heap[k]=heap[x];
		heap[x]=heap[0];
		position[heap[k].x][heap[k].y][heap[k].kind]=k;
		position[heap[x].x][heap[x].y][heap[x].kind]=x;
		x=k;
	}
}

void down(int x)
{
	int k;
	while((x+x<=sum&&heap[x+x].T<heap[x].T)||(x+x<sum&&heap[x+x+1].T<heap[x].T))
	{
		if(x+x==sum||heap[x+x].T<heap[x+x+1].T)
			k=x+x;
		else
			k=x+x+1;
		heap[0]=heap[k];
		heap[k]=heap[x];
		heap[x]=heap[0];
		position[heap[k].x][heap[k].y][heap[k].kind]=k;
		position[heap[x].x][heap[x].y][heap[x].kind]=x;
		x=k;
	}
}

bool init()
{
	scanf("%d %d %d %d %d %d",&n,&m,&st.x,&st.y,&ed.x,&ed.y);
	if(n==0)
		return true;
	memset(heap,0,sizeof(heap));
	memset(Time,0,sizeof(Time));
	memset(position,0,sizeof(position));
	for(i=1;i<=n;i++)
	{
		for(j=1;j<m;j++)
		{
			scanf("%d",&k);
			Time[i][j][1]=Time[i][j+1][3]=k;
		}
		if(i<n)
			for(j=1;j<=m;j++)
			{
				scanf("%d",&k);
				Time[i][j][0]=Time[i+1][j][2]=k;
			}
	}
	return false;
}

int main()
{
	cases=0;
	while(true)
	{
		if(init())
			break;
		sum=1;
		position[st.x][st.y][4]=1;
		heap[1].x=st.x;
		heap[1].y=st.y;
		heap[1].kind=4;
		heap[1].T=0;
		while(sum>0)
		{
			if(heap[1].x==ed.x&&heap[1].y==ed.y&&heap[1].kind==4)
				break;
			if(heap[1].kind==4)
			{
				for(i=0;i<4;i++)
					if(Time[heap[1].x][heap[1].y][i]!=0)
					{
						s.x=heap[1].x+change[i][0];
						s.y=heap[1].y+change[i][1];
						s.T=heap[1].T+Time[heap[1].x][heap[1].y][i]*2;
						s.kind=4;
						if(position[s.x][s.y][s.kind]==0)
						{
							sum++;
							heap[sum]=s;
							position[s.x][s.y][s.kind]=sum;
							up(sum);
						}
						else if(position[s.x][s.y][s.kind]>0)
						{
							k=position[s.x][s.y][s.kind];
							if(heap[k].T>s.T)
							{
								heap[k].T=s.T;
								up(k);
							}
						}
						s.kind=i;
						if(position[s.x][s.y][s.kind]==0)
						{
							sum++;
							heap[sum]=s;
							position[s.x][s.y][s.kind]=sum;
							up(sum);
						}
						else if(position[s.x][s.y][s.kind]>0)
						{
							k=position[s.x][s.y][s.kind];
							if(heap[k].T>s.T)
							{
								heap[k].T=s.T;
								up(k);
							}
						}
					}
			}
			else if(Time[heap[1].x][heap[1].y][heap[1].kind]!=0)
			{
				s.x=heap[1].x+change[heap[1].kind][0];
				s.y=heap[1].y+change[heap[1].kind][1];
				s.kind=4;
				s.T=heap[1].T+Time[heap[1].x][heap[1].y][heap[1].kind]*2;
				if(position[s.x][s.y][s.kind]==0)
				{
					sum++;
					heap[sum]=s;
					position[s.x][s.y][s.kind]=sum;
					up(sum);
				}
				else if(position[s.x][s.y][s.kind]>0)
				{
					k=position[s.x][s.y][s.kind];
					if(heap[k].T>s.T)
					{
						heap[k].T=s.T;
						up(k);
					}
				}
				s.kind=heap[1].kind;
				s.T=heap[1].T+Time[heap[1].x][heap[1].y][heap[1].kind];
				if(position[s.x][s.y][s.kind]==0)
				{
					sum++;
					heap[sum]=s;
					position[s.x][s.y][s.kind]=sum;
					up(sum);
				}
				else if(position[s.x][s.y][s.kind]>0)
				{
					k=position[s.x][s.y][s.kind];
					if(heap[k].T>s.T)
					{
						heap[k].T=s.T;
						up(k);
					}
				}
			}
			position[heap[1].x][heap[1].y][heap[1].kind]=-1;
			heap[1]=heap[sum];
			position[heap[1].x][heap[1].y][heap[1].kind]=1;
			sum--;
			down(1);
		}
		if(sum>0)
			printf("Case %d: %d\n",++cases,heap[1].T);
		else
			printf("Case %d: Impossible\n",++cases);
	}
	return 0;
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值