2016多校训练Contest3:1001 1002 1003 1007 1010 1011

嘛...1010猜对了结论没交上去..

剩下也各种梦游各种读错题各种没特判吃罚时...

感觉整个人状态都不太对劲


1001:Sqrt bo

根号5次之内看能否为1

大于某个数的时候肯定不成立。将大于某个长度的舍弃。剩下的直接直接暴力即可

记得n=0和n=1的特判

1002:Permutation Bo

我们枚举每个位置,计算期望。

两边期望相等,除去两边的中间所有期望相等

剩下的直接暴力即可

#include<map>
#include<cmath>
#include<queue>
#include<vector>
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
double c[10001];
int main()
{
	int n;
	while(scanf("%d",&n)!=EOF)
	{
		int i;
		for(i=1;i<=n;i++)
			scanf("%lf",&c[i]);
		if(n==1)
		{
			printf("%lf\n",c[1]);
			continue;
		}
		double x1=0,x2=0;
		for(i=3;i<=n;i++)
			x1+=(double)(i-1)*(double)(i-2);
		x1/=(double(n*(n-1)*(n-2)));
		double ans=0;
		for(i=2;i<=n-1;i++)
			ans+=x1*c[i];
		for(i=2;i<=n;i++)
			x2+=(double)(i-1);
		x2/=(double(n*(n-1)));
		ans+=c[1]*x2+c[n]*x2;
		printf("%lf\n",ans);
	}
	return 0;
}


1003:Life Winner Bo

马和国王直接很普通的DP就可以了

车的话只有n!=m的时候先手必负否则先手必胜

然后皇后的话我打表找了下规律。不妨令n<=m
假设第i个后手胜的位置是x,y

则y=x+i

关于i+1的求法是x++,然后当x在前面的x,y都未出现过,即为所求

#include<map>
#include<cmath>
#include<queue>
#include<vector>
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int f1[1002][1002],f3[1002][1002];
int v[100001];
int main()
{
	int T;
	scanf("%d",&T);
	int i,j;
	f1[1000][1000]=1;
	for(i=1000;i>=1;i--)
	{
		for(j=1000;j>=1;j--)
		{
			if(i==1000&&j==1000)
				continue;
			if(f1[i+1][j]==1||f1[i+1][j+1]==1||f1[i][j+1]==1)
				f1[i][j]=-1;
			else
				f1[i][j]=1;
		}
	}
	
	f3[1000][1000]=1;
	for(i=1000;i>=1;i--)
	{
		for(j=1000;j>=1;j--)
		{
			if(i==1000&&j==1000)
				continue;
			if(f3[i+2][j+1]==1||f3[i+1][j+2]==1)
				f3[i][j]=-1;
			else if(f3[i+2][j+1]==-1&&f3[i+1][j+2]==-1)
				f3[i][j]=1;
		}
	}
	
	
	int d=1,dx=1;
	memset(v,0,sizeof(v));
	while(d<=1000)
	{
		d++;
		while(v[d])
			d++;
		v[d]=dx;
		v[d+dx]=-dx;
		dx++;
	}
			
			
	while(T>0)
	{
		T--;
		int ty,n,m;
		scanf("%d%d%d",&ty,&n,&m);
		if(ty==1)
		{

			if(f1[1000-n+1][1000-m+1]==1)
				printf("G\n");
			else
				printf("B\n");
		}
		else if(ty==2)
		{
			if(n==m)
				printf("G\n");
			else
				printf("B\n");
		}
		else if(ty==3)
		{
			if(f3[1000-n+1][1000-m+1]==1)
				printf("G\n");
			else if(f3[1000-n+1][1000-m+1]==-1)
				printf("B\n");
			else
				printf("D\n");
		}
		else if(ty==4)
		{
			if(n+v[n]==m)
				printf("G\n");
			else
				printf("B\n");
		}
	}
	return 0;
}


1007:Explorer Bo

树DP,维护有多少条链没匹配,如果大于两条即可以合并。

因此只要记录剩余1或者2条往上即可

transfer的次数=(叶子+1)/2

然后如果叶子为奇数。那肯定有某个叶子的链到某个祖先停止

我们记录这种情况,一起转移

#include<map>
#include<cmath>
#include<queue>
#include<vector>
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
struct line 
{
     int s,t;
     int x;
     int next;
}a[200001];
int head[100001];
int edge;
inline void add(int s,int t,int x)
{
	 a[edge].next=head[s];
     head[s]=edge;
     a[edge].s=s;
     a[edge].t=t;
     a[edge].x=x;
}
int fa[100001];
int deg[100001];
int f[100001][3][2];
int tf[3][2];
int son[100001];
inline void dfs(int d)
{
	int i,j,k;
	for(i=head[d];i!=0;i=a[i].next)
	{
		int t=a[i].t;
		if(t!=fa[d])
		{
			son[d]++;
			fa[t]=d;
			dfs(t);
		}
	}
}
inline void trdp(int d)
{	
	if(son[d]==0)
		f[d][2][1]=f[d][1][0]=0;
	else
	{
	//	f[d][1][0]=0;
		f[d][2][0]=0;
	}
	int i,j,k;
	for(i=head[d];i!=0;i=a[i].next)
	{
		int t=a[i].t;
		if(t!=fa[d])
		{
			fa[t]=d;
			trdp(t);
			memset(tf,127/3,sizeof(tf));
			for(j=1;j<=2;j++)
			{
				for(k=1;k<=2;k++)
				{
					int dx=(j+k-1)%2+1;
					tf[dx][0]=min(tf[dx][0],f[d][j][0]+f[t][k][0]+k);
					tf[dx][1]=min(tf[dx][1],f[d][j][0]+f[t][k][1]+k);
					tf[dx][1]=min(tf[dx][1],f[d][j][1]+f[t][k][0]+k);
				}
			}
			for(j=1;j<=2;j++)
			{
				f[d][j][0]=tf[j][0];
				f[d][j][1]=tf[j][1];
			}
		}
	}
	f[d][1][1]=min(f[d][2][0],f[d][1][1]);
	f[d][2][1]=min(f[d][1][0],f[d][2][1]);

}
int main()
{
//	freopen("1007.in","r",stdin);
//	freopen("1007.ans","w",stdout);
	int T;
	scanf("%d",&T);
	while(T>0)
	{
		T--;
		int n;
		scanf("%d",&n);
		edge=0;
		memset(f,127/3,sizeof(f));
		memset(head,0,sizeof(head));
		memset(a,0,sizeof(a));
		memset(fa,0,sizeof(fa));
		memset(son,0,sizeof(son));
		memset(deg,0,sizeof(deg));
		int i;
		int ss,tt;
		for(i=1;i<=n-1;i++)
		{
			scanf("%d%d",&ss,&tt);
			edge++;
			add(ss,tt,1);
			edge++;
			add(tt,ss,1);
			deg[ss]++;
			deg[tt]++;
		}
		int sx=0;
		for(i=1;i<=n;i++)
			if(deg[i]==1)
				sx++;
		if(sx%2==0&&n!=1)
		{
			for(i=1;i<=n;i++)
			{
				if(deg[i]!=1)
				{
					dfs(i);
					trdp(i);
					break;
				}
			}
			if(n!=2)
				printf("%d\n",f[i][2][0]);
			else
				printf("1\n");
		}
		else
		{
			for(i=1;i<=n;i++)
			{
				if(deg[i]!=1)
				{
					dfs(i);
					trdp(i);
					break;
				}
			}
			printf("%d\n",min(f[i][2][1],f[i][2][0]));
		}
	}
	return 0;
}


1010:Rower Bo

av1/(v1*v1-v2*v2)

记得a=0的特判

据说是微积分。。不过我还没学过

#include<map>
#include<cmath>
#include<queue>
#include<vector>
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
double eps=1e-6;
int main()
{
	double a,b,c;
	while(scanf("%lf%lf%lf",&a,&b,&c)!=EOF)
	{
		if(fabs(a)<eps)
			printf("0.000000\n");
		else if(fabs(b-c)<eps||b<c)
			printf("Infinity\n");
		else
			printf("%lf\n",a*b/(b+c)/(b-c));
	}
	return 0;
}



1011:Teacher Bo

因为m<=10w,所以最多20w种不同答案

直接暴力即可

#include<map>
#include<cmath>
#include<queue>
#include<vector>
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
bool v[200001];
struct point
{
	int x,y;
}a[200001];
int main()
{
	int T;
	scanf("%d",&T);
	while(T>0)
	{
		T--;
		int n,m;
		scanf("%d%d",&n,&m);
		int i,j;
		for(i=1;i<=n;i++)
			scanf("%d%d",&a[i].x,&a[i].y);
		memset(v,false,sizeof(v));
		bool flag=false;
		for(i=1;i<=n;i++)
		{
			for(j=i+1;j<=n;j++)
			{
				int dis=abs(a[i].x-a[j].x)+abs(a[i].y-a[j].y);
				if(!v[dis])
					v[dis]=true;
				else
				{
					flag=true;
					break;
				}
			}
			if(flag)
				break;
		}
		if(flag)
			printf("YES\n");
		else
			printf("NO\n");
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值