zoukankan      html  css  js  c++  java
  • [Ozon Tech Challenge 2020][Codeforces 1305A~1305F]

    这场迅速签到后就被F题给教育了...挂机了足足有80+min_(:з」∠)_还是要提高下自己的姿势水平

    1305A - Kuroni and the Gifts

    将两个数组分别排序后输出即可

    #include<bits/stdc++.h>
    using namespace std;
    #define N 110
    int T,n,a[N],b[N];
    int main()
    {
        scanf("%d",&T);
        while(T--)
          {
          scanf("%d",&n);
          for(int i=1;i<=n;i++)scanf("%d",&a[i]);
          for(int i=1;i<=n;i++)scanf("%d",&b[i]);
          sort(a+1,a+n+1);
          sort(b+1,b+n+1);
          for(int i=1;i<=n;i++)printf("%d%c",a[i],i<n?' ':'
    ');
          for(int i=1;i<=n;i++)printf("%d%c",b[i],i<n?' ':'
    ');
          }
    }
    View Code

    1305B - Kuroni and Simple Strings

    这题开场还卡了一下...做完D才想出来_(:з」∠)_

    左右两边扫一下,把左边的'('和右边的')'一个个去掉直到两个指针相交为止即可

    可以证明最多只用操作一次,比赛时没想太多就直接set莽了

    #include<bits/stdc++.h>
    using namespace std;
    #define N 1010
    int n,k,m[N],f[N][N];
    set<int>a,b;
    string s;
    int main()
    {
        cin>>s;
        n=s.size();
        for(int i=0;i<n;i++)
          if(s[i]=='(')a.insert(i+1);
          else b.insert(i+1);
        while(a.size() && b.size())
          {
          auto l=a.begin();
          auto r=b.rbegin();
          if((*l)>(*r))break;
          k++;
          while(l!=a.end() && r!=b.rend() && (*l)<(*r))
            f[k][++m[k]]=*l,f[k][++m[k]]=*r,l++,r++;
          for(int i=1;i<=m[k];i++)
            if(a.count(f[k][i]))a.erase(f[k][i]);
            else b.erase(f[k][i]);
          }
        printf("%d
    ",k);
        for(int i=1;i<=k;i++)
          {
          sort(f[i]+1,f[i]+m[i]+1);
          printf("%d
    ",m[i]);
          for(int j=1;j<=m[i];j++)
            printf("%d%c",f[i][j],j<m[i]?' ':'
    ');
          }
        return 0;
    }
    View Code

    1305C - Kuroni and Impossible Calculation

    由抽屉原理可知,当(n>m)时,必定存在两个(a_i)模(m)同余,此时答案为(0)

    否则可以直接(O(n^2))暴力

    #include<bits/stdc++.h>
    using namespace std;
    #define N 200001
    #define LL long long
    LL n,m,ans=1,a[N];
    int main()
    {
        scanf("%lld%lld",&n,&m);
        for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
        if(n>m)return printf("0
    "),0;
        for(int i=1;i<=n;i++)
          for(int j=i+1;j<=n;j++)
            ans=ans*abs(a[i]-a[j])%m;
        return printf("%lld
    ",ans),0;
    }
    View Code

    1305D - Kuroni and the Celebration

    此题做法很多

    可以发现一棵树度数为1的点至少会有一个,因此可以每次挑出两个度数为1的点(x,y)进行询问,若结果等于其中一个点,则其必定为根。否则删除这两个点并把新出现的度数为1的点加入集合,最坏情况就是恰好询问(lfloor frac{n}{2} floor)次

    #include<bits/stdc++.h>
    using namespace std;
    #define N 1001
    int n,u,v;
    set<int>d[N],s,t;
    int ask(int x,int y)
    {
        int res=0;
        printf("? %d %d
    ",x,y);
        fflush(stdout);
        scanf("%d",&res);
        return res;
    }
    void del(int x)
    {
        for(auto y:d[x])
          {
          d[y].erase(x);
          if(d[y].size()==1)
            t.insert(y);
          }
        d[x].clear();
    }
    int main()
    {
        scanf("%d",&n);
        for(int i=2;i<=n;i++)
          {
          scanf("%d%d",&u,&v);
          d[u].insert(v);
          d[v].insert(u);
          }
        for(int i=1;i<=n;i++)
          {
          s.insert(i);
          if(d[i].size()==1)t.insert(i);
          }
        while(s.size()>1)
          {
          int x=*t.begin();
          t.erase(x);
          int y=*t.begin();
          t.erase(y);
          int res=ask(x,y);
          if(res==x || res==y)
            return printf("! %d
    ",res),0;
          s.erase(x),s.erase(y),del(x),del(y);
          }
        return printf("! %d
    ",*s.begin()),0;
    }
    View Code

    1305E - Kuroni and the Score Distribution

    凭直觉可以得出,当(a_i=i)时满足条件的三元组最多,为(sum_{i=1}^n lfloor frac{i-1}{2} floor)。先把这个值求出来,若其(<m)则一定无解

    每次赋值时判断当前的组数是否会溢出,若不会溢出将(m)减去当前的贡献。若当前把(a_i)赋值为(i)后会出现溢出的情况,把它赋值成(a_{i-1}+a_{i-2m})即可,这时(a_i)就等于(a_{i-k}+a_{i-2m+k-1}),恰好有(m)对这样的组合。当(m=0)时,可以直接将后面的几个数赋值成(1e9, 1e9-x, 1e9-2x,...)这样的形式,注意(x)的取值就好了。我是直接取(x=2cdot maxleft { a_i ight })

    #include<bits/stdc++.h>
    using namespace std;
    #define N 5001
    int n,m,s,a[N],mx;
    int main()
    {
        mx=999999999;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)s+=(i-1)/2;
        if(s<m)return printf("-1
    "),0;
        for(int i=1;i<=n;i++)
          {
          if(m==0)
            {
            for(int j=n;j>=i;j--)
              a[j]=mx,mx-=2*max(1,a[i-1]);
            break;
            }
          if(m<(i-1)/2)a[i]=a[i-1]+a[i-2*m],m=0;
          else a[i]=i,m-=(i-1)/2;
          }
        for(int i=1;i<=n;i++)
          printf("%d%c",a[i],i<n?' ':'
    ');
        return 0;
    }
    View Code

    1305F - Kuroni and the Punishment

    做这题的时候感受到了明显的智商被压制

    随机取(30)个(a_i),分别对(a_i, a_i-1, a_i+1)分解质因数后,把他们的质因子放入集合。之后对集合内的数一一作为(gcd)求操作次数取最小值即可

    补充一下证明:可以发现若将2作为(gcd),则答案最多不超过(n),因此需要操作两次的数字个数不会超过(lfloor frac{n}{2} floor)个,由此可以得出至少有一半的数操作次数(le 1),于是只要我们找到其中一个这样的数并对该数字及其周围的数的质因子进行判断即可。这样每次随机取一个能有(frac{1}{2})的正确概率,取30个已经足够保险

    #include<bits/stdc++.h>
    using namespace std;
    #define N 200001
    #define LL long long
    LL n,a[N],ans=N;
    set<LL>s;
    void rua(LL n)
    {
        for(LL i=2;i*i<=n;i++)
          while(n%i==0)s.insert(i),n/=i;
        if(n>1)s.insert(n);
    }
    LL cal(LL x)
    {
        LL res=0;
        for(LL i=1;i<=n;i++)
          res+=min(x-a[i]%x,a[i]>=x?a[i]%x:x);
        return res;
    }
    int main()
    {
        scanf("%lld",&n);
        for(LL i=1;i<=n;i++)
          scanf("%lld",&a[i]);
        srand(time(0)),random_shuffle(a+1,a+n+1);
        for(LL i=1;i<=30;i++)
          rua(a[i]-1),rua(a[i]),rua(a[i]+1);
        for(auto i:s)ans=min(ans,cal(i));
        return printf("%lld
    ",ans),0;
    }
    View Code
  • 相关阅读:
    QT5.4 vs2013静态加载插件的sqlite静态编译
    四个漂亮的CSS样式表
    程序猿写的程序将如何打包成安装包(最简单)
    cocos2d的-X- luaproject的LUA脚本加密
    【【分享】深入浅出WPF全系列教程及源码 】
    C#的StringBuilder 以及string字符串拼接的效率对照
    【Android中Broadcast Receiver组件具体解释 】
    【蜗牛—漫漫IT路之大学篇(九) 】
    【分布式存储系统sheepdog 】
    C#异步调用
  • 原文地址:https://www.cnblogs.com/DeaphetS/p/12406420.html
Copyright © 2011-2022 走看看