zoukankan      html  css  js  c++  java
  • Codeforces Round #580 (Div. 2)赛后总结

    本总结仅有A,B,C,D四题,E题作为交互题,不会!

    A:Choose Two Numbers 

    没啥意思,因为CF只要求任意一组解,并且两个数列均为正整数,那么果断求两个数列最大值之和,这样可以保证最大值之和一定不会存在于原数列中。

    #include<iostream>
    using namespace std;
    int n,m,a1=-998244353,a2=-998244353,k;
    int main()
    {
        cin>>n;
        for(int i=1;i<=n;i++)
        {
            cin>>k;
            a1=max(a1,k);
        }
        cin>>m;
        for(int i=1;i<=m;i++)
        {
            cin>>k;
            a2=max(a2,k);
        }
        cout<<a1<<' '<<a2;
        return 0;
    } 
    A

    B:Make Product Equal One

    这个稍微有点意思了,果断贪心。首先将每个数都先变成离自己最近的±1,也就是正数变成1,负数变成-1,同时记录变成-1数的个数和是否有0的存在。

    对于0,先将其变成1。

    下面判断-1的个数Mod2是否为0,如果为0直接输出答案,否则看当前是否有0的存在。如果有0的存在,也直接输出,视为将变为1的0变成-1,cost不变。如果没有0的存在,就在原cost的基础上+2,视为将某个1变成-1.

    #include<iostream>
    #include<cstdio>
    using namespace std;
    long long int s[100001],ans,mod,mix=998244353,maxx=-998244353,flag=0;
    int n;
    int main()
    {
        cin>>n;
        for(int i=1;i<=n;i++)
        {
            cin>>s[i];
            if(s[i]>=0)
            {
                ans+=max(s[i]-1,1LL*0);
                if(s[i]==0)
                {
                    flag=1;
                    ans++;
                }
                mix=min(mix,s[i]);
            }
            else
            {
                ans-=s[i]+1;
                maxx=max(maxx,s[i]);
                mod++;
            }
        }
        if(mod%2==0)
        {
            cout<<ans;
            return 0;
        }
        else
        {
            if(flag==1)
            {
                ;
            }
            else
            {
                ans+=2;
            }
            cout<<ans;
            return 0;
        }
    }
    B

    C: Almost Equal

    这个更有意思,题意可知要将这些数排成环,保证每连续N个数的和之间的差不超过1.

    给出一种神奇的构造方法。假定N=3,一共6个数,分别记作a,a+1,b,b+1,c,c+1.那么a=1,b=3,c=5,

    这样可以得知abc三个前缀一定要顺序排列,保证每一份均为a+b+c+x。

    并且相邻两个数一定是一个带有+1,一个不带有+1(否则就会出现有一组没有+1,或者有一组3个+1)

    则针对N=3的合法排列有 a,b+1,c,a+1,b,c+1;

    然后我们发现 这个排列刚好是样例1N=3时给出的答案。

    下面我们来考虑怎样判断不可能情况。不可能情况也就是有两个+1连在一起了,也就是N为偶数的情况。

    N=4有:a,b+1,c,d+1, a+1,b,c+1,d;

    可以截取:d+1---c+1 和 d---c

    第一个区间==a+b+c+d+3,第二个区间==a+b+c+d+1

    所以,N为偶数的情况不可取

    #include<iostream>
    #include<cstdio>
    using namespace std;
    int n,ke[200001],cnt=0;
    int main()
    {
        cin>>n;
        if(n%2==0)
        {
            cout<<"NO";
            return 0;
        }
        for(int i=1;i<=n;i+=2)
        {
            
            ke[i]=i*2-1;
            ke[i+n]=ke[i]+1;
        }
        for(int i=2;i<=n;i+=2)
        {
            ke[i]=i*2;
            ke[i+n]=ke[i]-1;
        }
        cout<<"YES"<<endl;
        for(int i=1;i<=2*n;i++)
        {
            cout<<ke[i]<<' ';
        }
        return 0;
    }
    C

    D:Shortest Cycle

    出题人备注:一个环至少有3个点

    这个就有一定的坑爹之处了,众所周知求最小环是N^3的时间复杂度,那如何缩小N?

    观察可知,最大的数一共60位,那么如果数字的数量超过2*60,就一定可以保证有3个点两两AND!=0;

    假设前60个数在2进制上均为最高位为1,其他位为0,那么这60个数中间没有任意两个数AND!=0。但是这个时候随便来一个二进制少于60位的就一定有至少一对数字AND!=0。这个很容易理解。也很方便就可以类推到3个点。

    下面就可以把N拘束在120以内了。Floyd求最小环即可!

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    long long int n=0,vis[100005],t,ans=0x3f3f3f3f,xl;
    long long int dis[201][201];
    long long int edge[201][201];
    long long int a[100005];
    int main()
    {
        cin>>t;
        //memset(dis,0x3f3f3f3f,sizeof(dis));
        //memset(edge,0x3f3f3f3f,sizeof(edge));
        for(int i=1;i<=t;i++)
        {
            cin>>a[i];
            if(a[i]!=0)
            {
                n++;
                vis[n]=a[i];
            }
        }
        if(n>2*60)
        {
            cout<<3;
            return 0;
        }
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=n;j++)
            {
                if(((vis[i]&vis[j])!=0)&&i!=j)
                {
                    dis[i][j]=1;
                    edge[i][j]=1;
                }
                else
                    dis[i][j]=edge[i][j]=0x3f3f3f3f;
            }
        }
        for(int k=1;k<=n;k++)
        {
            for(int i=1;i<k;i++)
            {
                for(int j=i+1;j<k;j++)
                {
                    ans=min(ans,dis[i][j]+edge[i][k]+edge[k][j]);
                }
            }
            for(int i=1;i<=n;i++)
            {
                for(int j=1;j<=n;j++)
                {
                    dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
                }
            }
        }
        if(ans==0x3f3f3f3f)
        {
            cout<<-1; 
        }
        else
            cout<<ans;
        return 0;
    } 
    D

    完结撒花!

  • 相关阅读:
    湖南省第6届程序大赛第6题 Biggest Number
    湖南省第6届程序大赛第5题 内部收益率
    湖南省第6届程序大赛第4题 台球碰撞
    湖南省第6届程序大赛第3题 数字整除
    湖南省第6届程序大赛第二题 弟弟的作业
    湖南省第6届程序设计大赛第一题 汽水瓶
    Nginx 负载均衡配置
    Nginx 反向代理流程
    Nginx 对客户端请求的特殊处理
    Nginx文件操作的优化
  • 原文地址:https://www.cnblogs.com/XLINYIN/p/11380523.html
Copyright © 2011-2022 走看看