zoukankan      html  css  js  c++  java
  • 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;
    }
    
  • 相关阅读:
    HDU 3572 Task Schedule(拆点+最大流dinic)
    POJ 1236 Network of Schools(Tarjan缩点)
    HDU 3605 Escape(状压+最大流)
    HDU 1166 敌兵布阵(分块)
    Leetcode 223 Rectangle Area
    Leetcode 219 Contains Duplicate II STL
    Leetcode 36 Valid Sudoku
    Leetcode 88 Merge Sorted Array STL
    Leetcode 160 Intersection of Two Linked Lists 单向链表
    Leetcode 111 Minimum Depth of Binary Tree 二叉树
  • 原文地址:https://www.cnblogs.com/forward-985/p/13910341.html
Copyright © 2011-2022 走看看