您的位置:首页 > 其它

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

2016-07-27 16:02 531 查看
嘛...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
*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
==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;
}


Sqrt Bo
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: