Contest 5

  A:这我怎么没学傻了啊。整个一傻逼题一眼容斥我连暴力都写不出来啊。显然序列是没有什么用的,考虑求众数小于x的概率,显然可以枚举有几个超过容斥一发。虽然要算的组合数非常大,发现可以抵消很大一部分,最后算组合数是O(n)的,总复杂度O(Tn2logn)。精度可能会有问题。

#include<iostream> 
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
int read()
{
    int x=0,f=1;char c=getchar();
    while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
    while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
    return x*f;
}
#define N 260
int n,m,cnt[N];
long double f[N]; 
int main()
{
    freopen("sequence.in","r",stdin);
    freopen("sequence.out","w",stdout);
    while (scanf("%d %d",&n,&m)>0)
    {
        memset(cnt,0,sizeof(cnt));
        memset(f,0,sizeof(f));
        for (int i=1;i<=n+1;i++)
        {
            for (int j=0;j<=n/i;j++)
            {
                long double x=1;
                for (int k=n-i*j+m;k<=n+m-1;k++) x/=k;
                for (int k=n-i*j+1;k<=n;k++) x*=k;
                for (int k=m-j+1;k<=m;k++) x*=k;
                for (int k=2;k<=j;k++) x/=k;
                if (j&1) f[i]-=x;else f[i]+=x;
            }
            f[i]=1-f[i];
        }
        long double ans=0;
        for (int i=1;i<=n;i++) ans+=(f[i]-f[i+1])*i;
        printf("%.4Lf\n",ans);
    }
    return 0;
}
View Code

  B:暴力。预处理最小质因子做到快速质因数分解就可以了。

#include<iostream> 
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
int read()
{
    int x=0,f=1;char c=getchar();
    while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
    while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
    return x*f;
}
#define N 1000010
int n,prime[N],p[N],cnt=0,ans=N;
bool flag[N];
int main()
{
    freopen("game.in","r",stdin);
    freopen("game.out","w",stdout);
    n=read();
    flag[1]=1;
    for (int i=2;i<=n;i++)
    {
        if (!flag[i]) prime[++cnt]=i,p[i]=i;
        for (int j=1;j<=cnt&&prime[j]*i<=n;j++)
        {
            flag[prime[j]*i]=1;p[prime[j]*i]=prime[j];
            if (i%prime[j]==0) break;
        }
    }
    int m=n;
    while (m>1)
    {
        int x=p[m];
        for (int i=max(n-x+1,x+1);i<=n;i++)
        {
            int y=i;
            while (y>1)
            {
                ans=min(ans,max(p[y]+1,i-p[y]+1));
                y/=p[y];
            }
        }
        m/=x;
    }
    cout<<ans;
    return 0;
}
View Code

  C:左上角是黑色则无解,反之则可行。显然问题可以转化为是否能用偶数次将棋盘变白。每次取反左上角的格子都会被取反,所以偶数次操作一定无法改变该位置。同理奇数次操作一定会改变该位置,若左上角为白色则无法用奇数次操作完成,并且显然这是有解的,所以可以用偶数次完成。

#include<iostream> 
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
int read()
{
    int x=0,f=1;char c=getchar();
    while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
    while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
    return x*f;
}
#define N 110
int T,n,m,a[N][N];
int main()
{
    freopen("chess.in","r",stdin);
    freopen("chess.out","w",stdout);
    T=read();
    while (T--)
    {
        n=read(),m=read();
        for (int i=1;i<=n;i++)
            for (int j=1;j<=m;j++)
            {
                char c=getchar();
                while (c!='B'&&c!='W') c=getchar();
                a[i][j]=(c=='B'?1:0);
            }
        if (a[1][1]) printf("H\n");else printf("C\n");
    }
    return 0;
}
View Code

  result:200 rank1

 

posted @ 2018-10-03 23:57  Gloid  阅读(186)  评论(0编辑  收藏  举报