• Codeforces Round #678 (Div. 2)【ABC】


    比赛链接:https://codeforces.com/contest/1436

    A.Reorder

    题解

    经过模拟计算,观察到
    (sum_{i=1}^n sum_{j=i}^n frac{a_j}{j}=sum_{i=1}^n a_i)
    判断每个n个数的和sum与m是否相等即可

    代码

    #include<iostream>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    int main()
    {
        ios::sync_with_stdio(false);//关闭cin与scanf同步
        cin.tie(nullptr);
        int t;cin>>t;
        while(t--)
        {
            int n,m,x,sum=0;
            cin>>n>>m;
            for(int i=0;i<n;i++)
            {
                cin>>x;
                sum+=x;
            }
            if(sum==m)
                cout<<"YES"<<endl;
            else
                cout<<"NO"<<endl;
        }
        return 0;
    }
    

    B.Yet Another Bookshelf

    题意

    (要求构造一个n*n的矩阵满足:\ 1.矩阵的所有元素均为非负整数,不超过10^5.\ 2.矩阵所有的元素均为合数\ 3.矩阵中各行个列的和均为素数)

    题解

    ( 比赛的时候写的贼麻烦.\ 法一.\ 线性筛法求质数,check函数判是不是合数。\ 在n*n的矩阵中,让(n-1)*(n-1)的矩阵全填写1,特殊处理第n行,第n列,再特判(n,n)元素填哪个)

    代码

    #include<iostream>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    typedef long long ll;
    
    const int N=1e5+10;
    
    int p[N],cnt,st[N];
    int a[N];
    void init(int n)
    {
        for(int i=2;i<=n;i++)
        {
            if(!st[i])
                p[cnt++]=i;
            for(int j=0;p[j]<=n/i;j++)
            {
                st[i*p[j]]=1;
                if(i%p[j]==0)
                    break;
            }
        }
    }
    
    bool check(int x)
    {
        if (x < 2) return false;
        for (int i = 2; i <= x / i; i ++ )
            if (x % i == 0)
                return false;
        return true;
    }
    
    
    int main()
    {
        int t;cin>>t;
        init(10000);
        for(int j=1;j<=1000;j++)
        {
            if(p[j]>100)
            {
                a[j]=p[j];
            }
        }
        while(t--)
        {
            int n;cin>>n;
            ll ans;
            for(int i=1;i<=1000;i++)
            {
                if((a[i]-n+1)>=1&&!check(a[i]-n+1))//这个数不是质数
                {
                    ans=a[i]-n+1;
                    break;
                }
            }
            ll res;
            for(int k=1;k<=1000;k++)
            {
                if(check((ans*(n-1)+k))&&!check(k))
                {
                    res=k;
                    break;
                }
                
            }
            
            for(int i=1;i<=n;i++)
            {
                for(int j=1;j<=n;j++)
                {
                    if(i==n&&j==n)
                    {
                        cout<<res<<" ";
                    }
                    else if(i==n)
                        cout<<ans<<" ";
                    else if(j==n)
                        cout<<ans<<endl;
                    else
                        cout<<1<<" ";
                }
            }
            //大于n-1的最小的质数
        }
        return 0;
    }
    /*
    1 1 1 1e5-1
    */
    
    

    法二:
    (沿对角线填2*2的1矩阵(构造))

    1 1
    1 1
        1 1
        1 1  (还不对)
    1 1 
    1 1 1
      1 1 1
        1 1 1
          1 1 1
            1 1
               (对了)
    

    代码

    #include<iostream>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    
    const int N=1100;
    int a[N][N],n;
    
    void init()
    {
        int flag=false;
        for(int i=1;i<=N/10;i++)
        {
            if(flag==false)
            {
                for(int j=i;j<=i+1;j++)
                {
                    a[i][j]=1;
                }
                flag=true;
            }
            else
            {
                for(int j=i-1;j<=i;j++)
                    a[i][j]=1;
                i--;
                flag=false;
            }
        }
    }
    
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
        int t;cin>>t;
        init();
        while(t--)
        {
            cin>>n;
            for(int i=1;i<=n;i++)
            {
                for(int j=1;j<=n;j++)
                {
                    cout<<a[i][j]<<" ";
                }
                cout<<endl;
            }
            
        }
        return 0;
    }
    

    题解

    ( 想在pos位置上找到x,\ 如果二分的位置小于pos的话,说明这个位置的数应该<x ,sma++\ 如果二分的位置大于pos的话,说明这个位置的数应该>x ,big++\ 对于所有的全排列\ 从n-x(1~n中所有>x的数)选big的全排列\ 从x-1(1~n中所有<x的数)选sma的全排列\ pos位置上填x\ 剩下的所有数other全排列(n-big-sma-1)\ ans=A_{n-x}^{big} * A_{x-1}^{sma} *A_{other}^{other}\ 注意:一定要用题干中给定的二分方法来查找,否则即使方法正确,再判断边界时依然会有问题\ 比如 1 1 0 (在0位找1,0<=pos<=n-1) 正确答案为0,y总模板得1 )

    代码

    #include<iostream>
    #include<algorithm>
    using namespace std;
    
    const int mod=1e9+7;
    typedef long long ll;
    ll n,x,pos;
    
    ll A(int n,int m)
    {
        ll res=1;
        for(int i=0;i<m;i++)
        {
            res=res*(n-i)%mod;
        }
        return res;
    }
    
    int main()
    {
        cin>>n>>x>>pos;
        int l=0,r=n,small=0,big=0;
        while(l<r)
        {
            int mid=l+r+1>>1;
            if(mid<=pos)
            {
                if(mid!=pos)
                    small++;
                l=mid;
            }
            else
            {
                big++;
                r=mid-1;
            }
        }
        int other=n-big-small-1;
        // cout<<A(n-x,big)<<endl;
        // cout<<A(x-1,small)<<endl;
        // cout<<A(other,other)<<endl;
        cout<<A(n-x,big)*A(x-1,small)%mod*A(other,other)%mod;
    }
    
  • 相关阅读:
    [华为]字符串反转
    [华为]字符个数统计
    [华为]字符串分隔
    [华为]计算字符个数
    [华为]字符串最后一个单词的长度
    感悟-思考-生活
    [百度校招]打印全排列
    [阿里]逆序打印整数,要求递归实现
    [百度]数组中去掉连续重复的数字,只保留1个
    百度NLP三面
  • 原文地址:https://www.cnblogs.com/forward-985/p/13910341.html
Copyright © 2020-2023  润新知