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

8

#include<iostream>
#include<string>
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<vector>
using namespace std;
bool used[1000],f[1000];
int x[5],y[5];
int q[1000000];
vector<int>g[1000];
int n,b;

bool check(int x)
{
	memset(used,false,sizeof(used));
	int h=1,t=1;
	q[1]=x;
	used[x]=true;
	while(h<=t)
	{
		for(vector<int>::iterator i=g[q[h]].begin();i!=g[q[h]].end();i++)
			if(!used[*i])
			{
				q[++t]=*i;
				used[*i]=true;
			}
		h++;
	}
	for(int i=1;i<=b;i++)
		if((used[2*i-1]&&used[2*i-2])||(used[2*i-1]&&!f[2*i-1])||(used[2*i-2]&&!f[2*i-2]))
			return false;
	return true;
}

void solve()
{
	for(int i=0;i<2*b;i++)
		if(f[i])
			f[i]=check(i);
	for(int i=1;i<=b;i++)
		if(!f[2*i-1]&&!f[2*i-2])
		{
			printf("impossible\n");
			return;
		}
	for(int i=1;i<=b;i++)
		if(f[2*i-1]&&f[2*i-2])
			printf("?");
		else
		{
			if(f[2*i-1])
				printf("n");
			else
				printf("y");
		}
	printf("\n");
}

int main()
{
	int cnt=0;
	while(scanf("%d%d",&b,&n),b!=0&&n!=0)
	{
		for(int i=0;i<=2*b;i++)
			g[i].clear();
		memset(f,true,sizeof(f));
		for(int i=1;i<=n;i++)
		{
			int p;
			char c;
			scanf("%d",&p);
			for(int j=1;j<=p;j++)
			{
				scanf("%d %c",&x[j],&c);
				if(c=='y')
					y[j]=0;
				else
					y[j]=1;
			}
			if(p<=2)
				for(int j=1;j<=p;j++)
					f[(2*x[j]-1)^y[j]]=false;
			else
			{
				for(int j=1;j<=p;j++)
					for(int k=1;k<=p;k++)
						if(j!=k)
						{
							g[(2*x[j]-1)^y[j]].push_back((2*x[k]-2)^y[k]);
							g[(2*x[k]-1)^y[k]].push_back((2*x[j]-2)^y[j]);
						}
			}
		}
		printf("Case %d: ",++cnt);
		solve();
	}
	return 0;
}

9

#include<stdio.h>
#include<algorithm>
using namespace std;
const int maxn=100+10;
int cs=0,n,m;
double width[maxn],height[maxn],x[maxn],y[maxn],nx[maxn],ny[maxn],nwidth[maxn],nheight[maxn];
int ho[maxn],ve[maxn],up[maxn],down[maxn],left[maxn],right[maxn];
int ind[maxn],outer[maxn];
bool cmp(const int &a,const int &b)
{
	return x[a]+y[a]<x[b]+y[b];
}

int main()
{
	while(scanf("%d%d%lf%lf",&n,&m,&width[0],&height[0]),++cs,n)
	{
		x[0]=y[0]=nx[0]=ny[0]=ind[0]=0;
		for(int i=1;i<=n;++i)
		{
			scanf("%lf%lf%lf%lf",&x[i],&y[i],&width[i],&height[i]);
			scanf("%d%d%d%d%d%d",&ho[i],&ve[i],&up[i],&down[i],&left[i],&right[i]);
			if(ho[i]+left[i]+right[i]==0)
				right[i]=1;
			if(ve[i]+up[i]+down[i]==0)
				up[i]=1;
			ind[i]=i;
		}
		sort(ind+1,ind+n+1,cmp);
		for(int i=1;i<=n;++i)
			for(int j=i-1;j>=0;--j)
				if(x[ind[j]]<x[ind[i]]&&y[ind[j]]<y[ind[i]]&&x[ind[j]]+width[ind[j]]>x[ind[i]]+width[ind[i]]
				&&y[ind[j]]+height[ind[j]]>y[ind[i]]+height[ind[i]])
				{
					outer[ind[i]]=ind[j];
					break;
				}
		for(int i=n;i>0;--i)
			x[ind[i]]-=x[outer[ind[i]]],y[ind[i]]-=y[outer[ind[i]]];
		for(int q=1;q<=m;++q)
		{
			scanf("%lf%lf",&nwidth[0],&nheight[0]);
			for(int i=1,cur;i<=n;++i)
			{
				cur=ind[i];
				double w0=0,h0=0;
				if(!ho[cur])
					w0+=width[cur];
				if(!ve[cur])
					h0+=height[cur];
				if(!up[cur])
					h0+=y[cur];
				if(!down[cur])
					h0+=height[outer[cur]]-height[cur]-y[cur];
				if(!left[cur])
					w0+=x[cur];
				if(!right[cur])
					w0+=width[outer[cur]]-width[cur]-x[cur];
				if(ho[cur])
					nwidth[cur]=width[cur]*(nwidth[outer[cur]]-w0)/(width[outer[cur]]-w0);
				else
					nwidth[cur]=width[cur];
				if(ve[cur])
					nheight[cur]=height[cur]*(nheight[outer[cur]]-h0)/(height[outer[cur]]-h0);
				else
					nheight[cur]=height[cur];
				if(up[cur])
					ny[cur]=y[cur]*(nheight[outer[cur]]-h0)/(height[outer[cur]]-h0);
				else
					ny[cur]=y[cur];
				if(left[cur])
					nx[cur]=x[cur]*(nwidth[outer[cur]]-w0)/(width[outer[cur]]-w0);
				else
					nx[cur]=x[cur];
			}
			for(int i=1;i<=n;++i)
				nx[ind[i]]+=nx[outer[ind[i]]],ny[ind[i]]+=ny[outer[ind[i]]];
			printf("Case %d, resize operation %d:\n",cs,q);
			for(int i=1;i<=n;++i)
				printf("    Window %d, x = %.0lf, y = %.0lf, wdith = %.0lf, height = %.0lf\n",i,nx[i],ny[i],nwidth[i],nheight[i]);
		}
	}
	return 0;
}


10

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
using namespace std;
int f[105][500],tmp[500];
int mid,l,r;
const int inf=1000000;
struct node
{
	int v,c,next;
}edge[300];
int g[105];
int tt=0,n;

int addedge(int a,int b,int c)
{
	edge[++tt].v=b;
	edge[tt].c=c;
	edge[tt].next=g[a];
	g[a]=tt;
	return 0;
}

int updata(int &a,int b)
{
	if(b>a)
		a=b;
	return 0;
}

int check(int a)
{
	if(a>=-mid&&a<=mid)
		return 1;
	return 0;
}

int dfs(int x,int fa)
{
	for(int i=0;i<=mid;i++)
		f[x][i]=-inf;
	f[x][0]=0;
	int y;
	for(int i=g[x];i;i=edge[i].next)
		if(edge[i].v!=fa)
		{
			dfs(edge[i].v,x);
			for(int j=0;j<=mid;j++)
			{
				tmp[j]=f[x][j];
				f[x][j]=-inf;
			}
			y=edge[i].v;
			for(int j=0;j<=mid;j++)	if(tmp[j]!=-inf)
				for(int k=0;k<=mid;k++) if(f[y][k]!=-inf)
				{
					if(check(j+k-edge[i].c)&&check(tmp[j]+f[y][k]-edge[i].c))
						updata(f[x][max(j,k-edge[i].c)],min(tmp[j],f[y][k]-edge[i].c));
					edge[i].c-=60;
					if(check(j+k-edge[i].c)&&check(tmp[j]+f[y][k]-edge[i].c))
						updata(f[x][max(j,k-edge[i].c)],min(tmp[j],f[y][k]-edge[i].c));
					edge[i].c+=60;
				}
		}
	return 0;
}

int main()
{
	int a,b,c,test=0;
	while(scanf("%d",&n)&&n)
	{
		for(int i=1;i<=n;i++)
			g[i]=0;
		tt=0;
		for(int i=1;i<n;i++)
		{
			scanf("%d%d%d",&a,&b,&c);
			c=c%60;
			addedge(a,b,c);
			addedge(b,a,c);
		}
		l=-1;r=300;
		while(l+1<r)
		{
			mid=(l+r)/2;
			dfs(1,0);
			int i;
			for(i=0;i<=mid;i++)
				if(f[1][i]>-inf)
					break;
			if(i==mid+1)
				l=mid;
			else
				r=mid;
		}
		printf("Case %d: %d\n",++test,r);
	}
	return 0;
}

11

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<string>
using namespace std;
string s[500];
long long f[210][210];
long long inf=1LL<<60;
int lc[210][210];
int len[210];
int p[210];
int n;

void solve()
{
	for(int i=0;i<n;i++)
		for(int j=0;j<n;j++)
			f[i][j]=inf;
	for(int i=0;i<n;i++)
		for(int j=0;j<n;j++)
		{
			int k;
			int l=min(len[i],len[j]);
			for(k=0;k<l;k++)
				if(s[i][len[i]-l+k]!=s[j][len[j]-l+k])
					break;
			lc[i][j]=k;
		}
	for(int i=2;i<n;i+=2)
		f[i][i+1]=1;
	for(int i=0;i<n;i++)
		for(int j=0;j<n;j++)
			if(lc[i][j]==len[j]||lc[i][j]==len[i])
				f[i][j]=0;
	for(int i=0;i<n;i++)
		p[i]=i;
	for(int i=0;i<n;i++)
		for(int j=i+1;j<n;j++)
			if(len[p[j]]<len[p[i]])
				swap(p[i],p[j]);
	for(int _k=0,k=p[_k]; _k<n; _k++,k=p[_k])
		for(int _i=0,i=p[_i]; _i<n; _i++,i=p[_i])
			for(int _j=0,j=p[_j]; _j<n; _j++,j=p[_j])
			{
				int l=min(len[i],len[j]);
				if(l>=len[k]&&lc[i][j]+len[k]>=l)
					if(f[i][k]+f[k][j]<f[i][j])
						f[i][j]=f[i][k]+f[k][j];
			}
}

int main()
{
	int test=0;
	while(cin>>s[0])
	{
		if(s[0]==".")
			break;
		cin>>s[1]>>n;
		for(int i=1;i<=n;i++)
			cin>>s[i*2]>>s[i*2+1];
		n=n*2+2;
		for(int i=0;i<n;i++)
			len[i]=s[i].size();
		solve();
		if(f[0][1]==inf)
			printf("Case %d: No solution\n",++test);
		else
		{
			printf("Case %d: ",++test);
			cout<<f[0][1]<<endl;
		}
	}
	return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值