zoukankan      html  css  js  c++  java
  • Codeforces Round #519 by Botan Investments翻车记

      A:枚举答案即可。注意答案最大可达201,因为这个wa了一发瞬间爆炸。

    #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 n,a[N],mx;
    int main()
    {
    /*#ifndef ONLINE_JUDGE
        freopen("a.in","r",stdin);
        freopen("a.out","w",stdout);
    #endif*/
        n=read();
        int tot=0;
        for (int i=1;i<=n;i++) mx=max(mx,a[i]=read()),tot+=a[i];
        for (int i=mx;i<=201;i++)
        {
            int cnt=0;
            for (int j=1;j<=n;j++) cnt+=i-a[j];
            if (cnt>tot) {cout<<i;return 0;}
        }
        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 1010
    int n,a[N],b[N],cnt=0,c[N];
    int main()
    {
    /*#ifndef ONLINE_JUDGE
        freopen("a.in","r",stdin);
        freopen("a.out","w",stdout);
    #endif*/
        n=read();
        for (int i=1;i<=n;i++) a[i]=read();
        for (int k=1;k<=n;k++)
        {
            bool flag=1;
            for (int i=1;i<=k;i++) b[i]=a[i]-a[i-1];
            for (int i=k+1;i<=n;i++) if (a[i]-a[i-1]!=b[(i-1)%k+1]) {flag=0;break;}
            if (flag) c[++cnt]=k;
        }
        cout<<cnt<<endl;
        for (int i=1;i<=cnt;i++) cout<<c[i]<<' ';
        return 0;
    }
    View Code

      C:看了半天题。想了半天。每次都在字符的分界处翻转,就可以得到最优解(即a都在前面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 1010
    int n,a[N];
    bool flag[N];
    char s[N];
    int main()
    {
    /*#ifndef ONLINE_JUDGE
        freopen("a.in","r",stdin);
        freopen("a.out","w",stdout);
    #endif*/
        scanf("%s",s+1);
        n=strlen(s+1);
        for (int i=1;i<=n;i++) a[i]=s[i]=='b';
        for (int i=1;i<=n;i++)
        {
            int t=i;
            while (t<n&&a[t+1]==a[i]) t++;
            if (t<n||a[i]==0) reverse(a+i+1,a+t+1),flag[t]=1;
            i=t;
        }
        for (int i=1;i<=n;i++) cout<<flag[i]<<' ';
        return 0;
    }
    View Code

      D:看了半天题。暴力匹配,如果失配这些数不可能再被计入答案。这样分成了很多段,将每段答案加起来即可。

    #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 100010
    #define M 12
    int n,m,a[M][N],p[M][N],q[12];
    long long ans;
    bool check()
    {
        for (int i=1;i<=m;i++)
        {
            q[i]++;
            if (q[i]>n) return 0;
        }
        for (int i=2;i<=m;i++)
        if (a[i][q[i]]!=a[i-1][q[i-1]]) return 0;
        return 1;
    }
    int main()
    {
    #ifndef ONLINE_JUDGE
        freopen("a.in","r",stdin);
        freopen("a.out","w",stdout);
    #endif
        n=read(),m=read();
        for (int i=1;i<=m;i++)
            for (int j=1;j<=n;j++)
            a[i][j]=read(),p[i][a[i][j]]=j;
        for (int i=1;i<=n;i++)
        {
            int x=i;
            q[1]=i;
            for (int j=2;j<=m;j++) q[j]=p[j][a[1][i]];
            while (x<n&&check()) x++;
            ans+=1ll*(x-i+2)*(x-i+1)/2;
            i=x;
        }
        cout<<ans;
        return 0;
    }
    View Code

      E:看了半天题。看题时间跟想+码的时间差不多了。首先给出的那些边显然可以直接排除。现在要求的是ansi=Σmin(xi+yj,xj+yi),可以将其变成ansi=Σmin(xi-yi-xj+yj,0)+xj+yi。这样min里面的东西只需要二分查一个前缀和。

    #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 300010
    int n,m,t=0;
    long long ans[N],b[N],pre[N],sum;
    struct data{int x,y;
    }a[N];
    int main()
    {
    #ifndef ONLINE_JUDGE
        freopen("a.in","r",stdin);
        freopen("a.out","w",stdout);
    #endif
        n=read(),m=read();
        for (int i=1;i<=n;i++) sum+=a[i].x=read(),a[i].y=read(),b[i]=a[i].y-a[i].x;
        sort(b+1,b+n+1);
        for (int i=1;i<=n;i++) pre[i]=pre[i-1]+b[i];
        for (int i=1;i<=m;i++)
        {
            int x=read(),y=read();
            ans[x]-=min(a[x].x+a[y].y,a[x].y+a[y].x),ans[y]-=min(a[x].x+a[y].y,a[x].y+a[y].x);
        }
        /*for (int i=1;i<=n;i++)
            for (int j=1;j<=n;j++)
            if (i!=j) ans[i]+=min(a[i].x-a[i].y+b[j],0)+a[i].y+a[j].x;*/
        for (int i=1;i<=n;i++)
        {
            ans[i]+=sum-a[i].x+1ll*a[i].y*(n-1);
            int l=1,r=n,t=0;
            while (l<=r)
            {
                int mid=l+r>>1;
                if (b[mid]+a[i].x-a[i].y<0) t=mid,l=mid+1;
                else r=mid-1;
            }
            ans[i]+=pre[t]+1ll*t*(a[i].x-a[i].y);
        }
        for (int i=1;i<=n;i++) printf("%I64d ",ans[i]);
        return 0;
    }
    close
    View Code

      F:做法似乎很多。比赛时只想到设f[i]为gcd=i时最少选多少元素,考虑通过与i的gcd数量是i的因子个数来优化,预处理可以向哪转移。这一部分看起来可以瞎优化到不错的效率,然而又wa又T最后弃疗了。

      题解给的是状压dp,没有太懂(upd:好像也是算方案数)。似乎也有不少随机化做法。

      感觉最妙的做法还是这样:强化这个题,求选k个数时的方案数。这显然可以莫比乌斯反演,预处理每个数在a中有多少个是其倍数即可,这可以利用调和级数做到log。显然最终答案若存在一定不超过7,于是复杂度O(n+vlogv)。这应该是保证正确性(取模后变成0什么的就算了吧)的最优做法了。把一个判定性问题转化为数数题居然能够简化问题非常有意思。

    #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 300010
    #define P 1000000007
    int n,a[N],mobius[N],prime[N],tot[N],cnt;
    int fac[N],inv[N];
    bool flag[N];
    int C(int n,int m)
    {
        if (m>n) return 0;
        return 1ll*fac[n]*inv[m]%P*inv[n-m]%P;
    }
    int main()
    {
    #ifndef ONLINE_JUDGE
        freopen("f.in","r",stdin);
        freopen("f.out","w",stdout);
    #endif
        n=read();
        for (int i=1;i<=n;i++) a[read()]++;
        flag[1]=1;mobius[1]=1;
        for (int i=2;i<=N-10;i++)
        {
            if (!flag[i]) prime[++cnt]=i,mobius[i]=-1;
            for (int j=1;j<=cnt&&prime[j]*i<=N-10;j++)
            {
                flag[prime[j]*i]=1;
                if (i%prime[j]==0) break;
                else mobius[prime[j]*i]=-mobius[i];
            }
        }
        fac[0]=1;for (int i=1;i<=N-10;i++) fac[i]=1ll*fac[i-1]*i%P;
        inv[0]=inv[1]=1;for (int i=2;i<=N-10;i++) inv[i]=P-1ll*(P/i)*inv[P%i]%P;
        for (int i=2;i<=N-10;i++) inv[i]=1ll*inv[i-1]*inv[i]%P;
        for (int i=1;i<=N-10;i++)
            for (int j=i;j<=N-10;j+=i)
            tot[i]+=a[j];
        for (int k=1;k<=7;k++)
        {
            int ans=0;
            for (int i=1;i<=N-10;i++)
            ans=((ans+mobius[i]*C(tot[i],k))%P+P)%P;
            if (ans) {cout<<k;return 0;}
        }
        cout<<-1;
        return 0;
    }
    View Code

      这场阅读量实在太大,读题感觉花了快有30min。A wa一发掉了至少30名非常惨了。

      result:rank 417 rating -6

       

  • 相关阅读:
    JavaScript 为字符串添加样式 【每日一段代码80】
    JavaScript replace()方法 【每日一段代码83】
    JavaScript for in 遍历数组 【每日一段代码89】
    JavaScript 创建用于对象的模板【每日一段代码78】
    html5 css3 新元素简单页面布局
    JavaScript Array() 数组 【每日一段代码88】
    JavaScript toUTCString() 方法 【每日一段代码86】
    位运算
    POJ 3259 Wormholes
    POJ 3169 Layout
  • 原文地址:https://www.cnblogs.com/Gloid/p/9868476.html
Copyright © 2011-2022 走看看