寒假集训-1.28

Educational Codeforces Round 83 (Rated for Div. 2)

https://codeforces.com/contest/1312

A - Two Regular Polygons

思路

几何题,求是否存在小正多边形与给出的正多边形中心一样且顶点位于大正多边形中,只需要将多边形的边数均分即可,直接判断n%m的值即可。

Code

#include<bits/stdc++.h>
#define IO  ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std; 
 
const int inf=0x3f3f3f3f;
typedef long long ll; 
const int N=2e5+7;
const ll mod=1e9+7;     

int main(){ 
    IO;
    int t=1;
    cin>>t;
    while(t--){ 
        int n,m;
        cin>>n>>m;
        if(n%m!=0)cout<<"NO"<<endl;
        else cout<<"YES"<<endl;
    }
    return 0;
}

B - Bogosort

思路

将给出数组变成一个新数组满足i-a[i]唯一。
直接从大到小排序,此序列i为增序,a[i]为非增序,所以i-a[i]为增序,满足唯一性。

Code

#include<bits/stdc++.h>
#define IO  ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std; 
 
const int inf=0x3f3f3f3f;
typedef long long ll; 
const int N=2e5+7;
const ll mod=1e9+7;    
 
int a[107];

bool cmp(int x,int y){return x>y;}

int main(){ 
    IO;
    int t=1;
    cin>>t;
    while(t--){ 
        int n,m;
        cin>>n;
        for (int i = 0; i < n; ++i)
        {
            cin>>a[i];
        }sort(a,a+n,cmp);
        for (int i = 0; i < n; ++i)
        {
            cout<<a[i]<<" ";
        }cout<<endl;
    }
    return 0;
}

C - Adding Powers

思路

题意为给出序列中的非零值是不是p个唯一的k的幂数之和。(p>=0)
首先预处理将k的幂数求出存为数组v,将给出序列扫一遍,对于第i个数a[i],因为每个数(k次幂)只能用一次,所以倒序遍历一遍v,若够减就减掉,遍历完v中所有可用的值后如果a[i]不是0则不满足题意。

Code

#include<bits/stdc++.h>
#define IO  ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std; 
 
const int inf=0x3f3f3f3f;
typedef long long ll; 
const int N=2e5+7;
const ll mod=1e9+7;    
 
ll a[37],b[37];

bool cmp(int x,int y){return x>y;}

ll ksm(ll x,ll y){
    ll p=1;
    while(y){
        if(y&1)p=p*x;
        x=x*x;
        y>>=1;
    }return p;
}

int main(){ 
    IO;
    int t=1;
    cin>>t;
    while(t--){ 
        ll n,k;
        cin>>n>>k;
        int flag=0;
        map<int,int>mp;
        ll maxn=0;
        for (int i = 0; i < n; ++i)
        {
            cin>>a[i];  
            maxn=max(maxn,a[i]);
        }
        if(k==1){
            cout<<"YES"<<endl;
            continue;
        } 
        vector<ll>v;
        for (int i = 0;; ++i)
        {
            ll p=ksm(k,(ll)i);
            v.push_back(p);
            if(p>=maxn)break;
        }
        sort(a,a+n,cmp); 
        int len=int(v.size());
        for (int i = 0; i < n; ++i)
        {
            if(!a[i])continue;
            int j=len-1;
            while((mp[j]||a[i]<v[j])&&j>=0)j--; 
            for (int p = j; p >= 0; --p)
            {
                if(mp[p]||a[i]<v[p])continue;
                a[i]-=v[p];
                mp[p]=1;
            } 
            if(a[i]){
                flag=1;  
            }
            if(flag)break;
        }
        if(!flag)cout<<"YES"<<endl;
        else cout<<"NO"<<endl;
    }
    return 0;
}

D - Count the Arrays

思路

组合数学题,因为整个序列中必须有n-1个不同的值,所以每次都从m个数中取出n-1个数,即C(m,n-1).
对于位置i,左边有i-1个位置,右边有n-i个位置,首先位置i是取出的n-1个数中最大的数,因此只剩n-2个数,左边的i-1个位置有C(n-2,i-1)种方案,因为顺序已经定了,所以选出i-1个数后右边的n-i-1个数的相对位置也已经确定,最后从i-1个数中选出1个放到右边满足存在一对相同的数,即为C(m,n-1)×C(n-2,i-1)×(i-1).
从2到n-1遍历一遍求和得出答案。
(一开始以为模数是1e9+7,被卡的怀疑人生)

Code

#include<bits/stdc++.h>
#define IO  ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std; 
 
const int inf=0x3f3f3f3f;
typedef long long ll; 
const int N=2e5+7;
const ll mod=998244353;    
 
ll f[N];

ll ksm(ll x,ll y){
    ll p=1;
    while(y){
        if(y&1)p=p*x%mod;
        x=x*x%mod;
        y>>=1;
    }return p%mod;
}

bool cmp(int x,int y){return x>y;}

ll C(int a,int b){
    return f[a]*ksm(f[b]*f[a-b]%mod,mod-2)%mod;
}

int main(){ 
    IO;
    int t=1;
    //cin>>t;
    f[0]=1;
    for (int i = 1; i <= N; ++i)
    {
        f[i]=(f[i-1]*i)%mod;
    }
    while(t--){ 
        ll n,m;
        cin>>n>>m;
        ll ans=0;
        for (int i = 2; i < n; ++i)
        {
            ans=(ans+C(m,n-1)%mod*C(n-2,i-1)%mod*(i-1)%mod)%mod;
        }cout<<ans<<endl;
    }
    return 0;
}

继续加油!!!

posted @ 2021-01-28 16:21  !^^!  阅读(76)  评论(0)    收藏  举报