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

8

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<string>
#include<vector>
#include<map>
#include<algorithm>
#include<math.h>
using namespace std;
#define PB push_back
#define MP make_pair
const int MaxN=3009;
const double Pi=acos(-1.0);
int N,M;
int X[MaxN],Y[MaxN],H[MaxN],Level[MaxN];

bool NearSea[MaxN],vis[MaxN];
string Name[MaxN];
char ch[2];
map<string,int> PointSet;
map<pair<int,int>,bool> EdgeSet;
vector<int>Height,Lake;
vector<pair<double,int>> e[MaxN];
int Union_H[MaxN],Union_Level[MaxN],belong[MaxN],Union_num;
int Union_e[MaxN][MaxN];
bool Union_NearSea[MaxN];

void AddEdge(int a,int b)
{
	EdgeSet.insert(MP(MP(a,b),true));
	double deg=atan2(double(Y[b]-Y[a]),X[b]-X[a]);
	e[a].PB(MP(deg,b));
}

void FloodFill(int x,int p)
{
	if(vis[x])
		return;
	belong[x]=p;
	for(int i=0;i<e[x].size();i++)
		if(H[e[x][i].second]==H[x])
			FloodFill(e[x][i].second,p);
}

void Init()
{
	Height.clear();
	PointSet.clear();
	for(int i=1;i<=N;i++)
	{
		scanf("\n%s%d%d%d",&ch,&X[i],&Y[i],&H[i]);
		Name[i].clear();
		Name[i].PB(ch[0]);
		Name[i].PB(ch[1]);
		Height.PB(H[i]);
		PointSet[Name[i]]=i;
		e[i].clear();
	}
	sort(Height.begin(),Height.end());
	Height.erase(unique(Height.begin(),Height.end()),Height.end());
	EdgeSet.clear();
	for(int i=1;i<=M;i++)
	{
		string u,v;
		u.clear();
		v.clear();
		scanf("\n%s",&ch);
		u.PB(ch[0]);
		u.PB(ch[1]);
		scanf("%s",&ch);
		v.PB(ch[0]);
		v.PB(ch[1]);
		AddEdge(PointSet[u],PointSet[v]);
		AddEdge(PointSet[v],PointSet[u]);
	}
	for(int i=1;i<=N;i++)
	{
		NearSea[i]=false;
		sort(e[i].begin(),e[i].end());
		for(int a=0;a+1<e[i].size();a++)
			if((e[i][a+1].first-e[i][a].first)>=Pi)
				NearSea[i]=true;
		if(e[i][0].first+2*Pi-e[i][e[i].size()-1].first>=Pi)
			NearSea[i]=true;
		for(int a=0;a<e[i].size();a++)
		{
			int b=(a+1)%e[i].size();
			if(EdgeSet.find(MP(e[i][a].second,e[i][b].second))!=EdgeSet.end());
			else
				NearSea[i]=true;
		}
	}
	Union_num=0;
	for(int i=1;i<=N;i++)
		vis[i]=false;
	for(int i=1;i<=N;i++)
		if(!vis[i])
			FloodFill(i,++Union_num);
	for(int i=1;i<=Union_num;i++)
		Union_NearSea[i]=false;
	for(int i=1;i<=Union_num;i++)
		Union_e[i][0]=0;
	for(int i=1;i<=N;i++)
		Union_H[belong[i]]=H[i];
	for(int i=1;i<=N;i++)
	{
		if(NearSea[i])
			Union_NearSea[belong[i]]=true;
		for(int j=0;j<e[i].size();j++)
			if(belong[i]!=belong[e[i][j].second])
				Union_e[belong[i]][++Union_e[belong[i]][0]]=belong[e[i][j].second];
	}
}

void Dfs(int x,int hi)
{
	if(vis[x])
		return;
	vis[x]=true;
	for(int i=1;i<=Union_e[x][0];i++)
		if(Union_H[Union_e[x][i]]<hi)
		{
			if(vis[Union_e[x][i]])
			{
				swap(Union_e[x][i],Union_e[x][Union_e[x][0]]);
				Union_e[x][Union_e[x][0]]=0;
				Union_e[x][0]--;
				i--;
			}
			else
				Dfs(Union_e[x][i],hi);
		}
}

void Solve()
{
	for(int i=1;i<=Union_num;i++)
		Union_Level[i]=0;
	for(int i=0;i<Height.size();i++)
	{
		for(int j=1;j<=Union_num;j++)
			vis[j]=false;
		for(int j=1;j<=Union_num;j++)
			if(Union_NearSea[j]&&Union_H[j]<Height[i])
			{
				Dfs(j,Height[i]);
			}
		for(int j=1;j<=Union_num;j++)
			if(!vis[j])
				Union_Level[j]=Height[i];
	}
	for(int i=1;i<=N;i++)
		Level[i]=Union_Level[belong[i]];
}

void FindLake(int x)
{
	if(vis[x])
		return;
	vis[x]=true;
	for(int i=0;i<e[x].size();i++)
		if(H[e[x][i].second]<Level[e[x][i].second]&&Level[x]==Level[e[x][i].second])
			FindLake(e[x][i].second);
}

void Output()
{
	Lake.clear();
	for(int i=1;i<=N;i++)
		vis[i]=false;
	for(int i=1;i<=N;i++)
		if(!vis[i]&&H[i]<Level[i])
		{
			Lake.PB(Level[i]);
			FindLake(i);
		}
		if(Lake.empty())
			printf(" 0\n");
		else
		{
			sort(Lake.begin(),Lake.end());
			for(int i=0;i,Lake.size();i++)
				printf(" %d\n",Lake[i]);
		}

}

int main()
{
	int Case=0;
	while(2==scanf("%d %d",&N,&M)&&(N||M))
	{
		Init();
		Solve();
		printf("Case %d:\n",++Case);
		Output();
	}
	return 0;
}

9

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
const int MAXN=10;
const int fx[4][2]={1,0, 0,1, -1,0, 0,-1};
int n,m,t;
int x[5],y[5],c[5];
int map[MAXN][MAXN];
bool chk[MAXN][MAXN];
int ans;
bool b[4];
inline int abs(int x)
{
	return x<0?-x:x;
}

void init()
{
	memset(map,0,sizeof(map));
	t=n*m;
	for(int i=1;i<=3;++i)
	{
		scanf("%d %d",x+i,y+i);
		c[i]=i*t/4;
		map[x[i]][y[i]]=i;
	}
	x[4]=0;
	y[4]=1;
	c[4]=t;
	map[0][1]=4;
}

inline bool cut(int x,int y)
{
	int i,tx,ty;
	for(i=0;i<4;++i)
	{
		tx=x+fx[i][0];
		ty=y+fx[i][1];
		b[i]=((tx>=0)&&(tx<n)&&(ty>=0)&&(ty<m)&&!chk[tx][ty]);
	}
	return (b[0]&&!b[1]&&b[2]&&!b[3])||(!b[0]&&b[1]&&!b[2]&&b[3]);
}

void dfs(int x1,int y1,int c1,int dep)
{
	if(dep==c[c1])
	{
		if(map[x1][y1]==c1)
			++c1;
		else
			return;
	}
	else if(map[x1][y1]>0)
		return;
	if(dep==t)
	{
		++ans;
		return;
	}
	if(abs(x[c1]-x1)+abs(y[c1]-y1)>c[c1]-dep)
		return;
	int i,tx,ty;
	for(i=0;i<4;++i)
	{
		tx=x1+fx[i][0];
		ty=y1+fx[i][1];
		if((tx>=0)&&(tx<n)&&(ty>=0)&&(ty<m)&&!chk[tx][ty]&&!cut(tx,ty))
		{
			chk[tx][ty]=true;
			dfs(tx,ty,c1,dep+1);
			chk[tx][ty]=false;
		}
	}
}

void solve()
{
	ans=0;
	memset(chk,0,sizeof(chk));
	chk[0][0]=true;
	dfs(0,0,1,1);
	printf("%d\n",ans);
}

int main()
{
	int CASE=0;
	while((scanf("%d %d",&n,&m)!=EOF)&&n&&m)
	{
		init();
		printf("Case %d: ",++CASE);
		solve();
		fflush(stdout);
	}
	return 0;
}

10

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
const int MAXN=20;
const int e2[]={0,1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288};
int n,x,y,t;
int a[MAXN];
int f[110][66000];
int g[66000];
int list[66000];
int next[66000];
inline int min(int a,int b)
{
	return a<b?a:b;
}

void init()
{
	t=0;
	scanf("%d %d",&x,&y);
	for(int i=1;i<=n;++i)
	{
		scanf("%d",a+i);
		t+=a[i];
	}
}

bool get(int x,int area,int s)
{
	if(f[x][s]!=-1)
		return f[x][s];
	int i,j,y=area/x;
	for(i=1;i<=(x>>1);++i)
	{
		for(j=list[i*y];j!=-1;j=next[j])
			if((j|s)==s)
			{
				if(get(min(i,y),i*y,j)&&get(min(x-i,y),area-i*y,s-j))
					return f[x][s]=1;
			}
	}
	for(i=1;i<=(y>>1);++i)
	{
		for(j=list[i*x];j!=-1;j=next[j])
			if((j|s)==s)
			{
				if(get(min(i,x),i*x,j)&&get(min(y-i,x),area-i*x,s-j))
					return f[x][s]=1;
			}
	}
	return f[x][s]=0;
}

void solve()
{
	if(t!=x*y)
	{
		printf("NO\n");
		return;
	}
	memset(g,0,sizeof(g));
	int i,j,k;
	for(i=0;i<e2[n+1];++i)
		for(j=1;j<=n;++j)
			if((i&e2[j])>0)
				g[i]+=a[j];
	memset(list,0xff,sizeof(list));
	for(i=0;i<e2[n+1];++i)
	{
		next[i]=list[g[i]];
		list[g[i]]=i;
	}
	memset(f,0xff,sizeof(f));
	f[0][0]=1;
	for(i=1;i<=n;++i)
	{
		k=(int)(sqrt(double(a[i])));
		for(j=1;j<=k;++j)
			if(a[i]%j==0)
				f[j][e2[i]]=1;
	}
	if(get(min(x,y),x*y,e2[n+1]-1))
		printf("Yes\n");
	else
		printf("No\n");
}

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

11
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<vector>
#include<math.h>
#include<string>
#include<stdlib.h>
using namespace std;
#define PB push_back
double fabs(double num)
{
	return num<0?-num:num;
}

double fmin(double num1,double num2)
{
	return num1<=num2?num1:num2;
}

double fmax(double num1,double num2)
{
	return num1>=num2?num1:num2;
}

double Sqr(double num)
{
	return num*num;
}

struct Point
{
	double X;
	double Y;
	double Z;
};

bool operator ==(Point A,Point B)
{
	return (A.X==B.X&&A.Y==B.Y&&A.Z==B.Z);
}

Point MakePoint(double X0,double Y0,double Z0)
{
	Point Ret;
	Ret.X=X0;
	Ret.Y=Y0;
	Ret.Z=Z0;
	return Ret;
}

Point operator + (Point A,Point B)
{
	return MakePoint(A.X+B.X,A.Y+B.Y,A.Z+B.Z);
}

Point operator - (Point A,Point B)
{
	return MakePoint(A.X-B.X,A.Y-B.Y,A.Z-B.Z);
}

double operator * (Point A,Point B)
{
	return A.X*B.X + A.Y*B.Y + A.Z*B.Z;
}

Point operator ^ (Point A,Point B)
{
	return MakePoint(A.Y*B.Z-A.Z*B.Y, A.Z*B.X-A.X*B.Z, A.X*B.Y-A.Y*B.X);
}

Point operator * (Point A,double x)
{
	return MakePoint(A.X*x,A.Y*x,A.Z*x);
}

Point operator / (Point A,double x)
{
	return MakePoint(A.X/x,A.Y/x,A.Z/x);
}

double Volume(Point A,Point B,Point C,Point D)
{
	return fabs(((B-A)^(C-A))*(D-A))/6.000;
}

double Distance(Point A,Point B)
{
	return sqrt(Sqr(A.X-B.X) + Sqr(A.Y-B.Y) + Sqr(A.Z-B.Z));
}

double Abs(Point p)
{
	return sqrt(Sqr(p.X)+Sqr(p.Y)+Sqr(p.Z));
}

vector<Point> Flat;
Point A,B,C,D,E,F,G,G_ABCD,G_ABCE,P[10];
double V_ABCD,V_ABCE;

void FindCentre()
{
	V_ABCD=Volume(A,B,C,D);
	V_ABCE=Volume(A,B,C,E);

	G_ABCD=(A+B+C+D)/4.000;
	G_ABCE=(A+B+C+E)/4.000;
	G=G_ABCD+((G_ABCE-G_ABCD)*V_ABCE)/(V_ABCD+V_ABCE);
}

bool SameSide(Point p1,Point p2,Point p3)
{
	Point Nor=(p2-p1)^(p3-p1);
	bool plus=false,minus=false;
	for(int i=1;i<=5;i++)
	{
		if(P[i]==p1||P[i]==p2||P[i]==p3)
			continue;
		double temp=(P[i]-p1)*Nor;
		if(temp<0)
			minus=true;
		else if(temp>0)
			plus=true;
	}
	if(plus&&minus)
		return false;
	Flat.clear();
	Flat.push_back(p1);
	Flat.push_back(p2);
	Flat.push_back(p3);
	for(int i=1;i<=5;i++)
	{
		if(P[i]==p1||P[i]==p2||P[i]==p3)
			continue;
		double temp=(P[i]-p1)*Nor;
		if(temp==0)
			Flat.push_back(P[i]);
	}
	return true;
}

Point Shadow(Point p,Point p1,Point p2,Point p3)
{
	Point Nor=(p2-p1)^(p3-p1);
	Point Nor0=(Nor*(Nor*(p-p1))/Abs(Nor)/Abs(Nor));
	return (p-Nor0);
}

double ShadowHeight(Point p,Point p1,Point p2,Point p3)
{
	Point Nor=(p2-p1)^(p3-p1);
	return fabs(Nor*(p-p1)/Abs(Nor));
}

bool SameSide(Point A,Point B,Point C,Point P)
{
	Point AB=B-A;
	Point AC=C-A;
	Point AP=P-A;

	Point v1=AB^AC;
	Point v2=AB^AP;

	return (v1*v2)>=0;
}

bool PointinTriangle(Point A,Point B,Point C,Point P)
{
	return SameSide(A,B,C,P)&&SameSide(B,C,A,P)&&SameSide(C,A,B,P);
}

bool PointInArea(Point p)
{
	for(int i=0;i<Flat.size();i++)
		for(int j=i+1;j<Flat.size();j++)
			for(int k=j+1;k<Flat.size();k++)
				if(PointinTriangle(Flat[i],Flat[j],Flat[k],p))
					return true;
	return false;
}

double DistanceToLine(Point P,Point A,Point B)
{
	if((B-A)*(P-A)>0.000 && (A-B)*(P-B)>0.000)
		return sqrt(Sqr(Distance(A,P))-Sqr((B-A)*(P-A)/Abs((B-A))));
	return fmin(Distance(A,P),Distance(B,P));
}

bool Balance(Point p)
{
	if(!PointInArea(p))
		return false;
	for(int i=0;i<Flat.size();i++)
		for(int j=i+1;j<Flat.size();j++)
		{
			Point P_i=Flat[i],P_j=Flat[j];
			int k;
			for(k=0;k<Flat.size();k++)
				if(k!=i&&k!=j)
					break;
			Point P_k=Flat[k];
			bool plus=false,minus=false;
			Point Nor=(P_j-P_i)^(P_k-P_i)^(P_j-P_i);
			for(int l=0;l<Flat.size();l++) if(l!=i&&l!=j)
			{
				if(Nor*(Flat[l]-P_i)>0)
					plus=true;
				else if(Nor*(Flat[k]-P_i)<0)
					minus=true;
			}
			if(plus&&minus)
				continue;
			if(DistanceToLine(p,P_i,P_j)<0.2)
				return false;
		}
		return true;
}

void FindHull()
{
	double Min_Answer=2000.000,Max_Answer=0.000;
	P[1]=A;P[2]=B;P[3]=C;P[4]=D;P[5]=E;P[6]=F;
	for(int i=1;i<=5;i++)
		for(int j=i+1;j<=5;j++)
			for(int k=j+1;k<=5;k++)
			{
				if(SameSide(P[i],P[j],P[k]))
				{
					Point G0=Shadow(G,P[i],P[j],P[k]);
					if(Balance(G0))
					{
						Min_Answer=fmin(Min_Answer,ShadowHeight(F,P[i],P[j],P[k]));
						Max_Answer=fmax(Max_Answer,ShadowHeight(F,P[i],P[j],P[k]));
					}
				}
			}
	cout<<fixed<<Min_Answer<<" "<<Max_Answer<<"\n";
}

int main()
{
	cout.precision(5);
	int Case=0,deg;
	char ss[200];
	while(gets(ss))
	{
		if(strlen(ss)==1&&ss[0]=='0')
			break;
		scanf(ss,"%lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf",
			&A.X,&A.Y,&A.Z,&B.X,&B.Y,&B.Z,
			&C.X,&C.Y,&C.Z,&D.X,&D.Y,&D.Z,
			&E.X,&E.Y,&E.Z,&F.X,&F.Y,&F.Z);
		cout<<"Case "<<++Case<<": ";
		FindCentre();
		FindHull();
	}
	return 0;
}




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值