码迷,mamicode.com
首页 > 其他好文 > 详细

Educational Codeforces Round 83 (Rated for Div. 2)

时间:2020-03-10 21:26:10      阅读:49      评论:0      收藏:0      [点我收藏+]

标签:记录   ++   mat   names   组合   ring   using   printf   math   

Educational Codeforces Round 83 (Rated for Div. 2)

A. Two Regular Polygons

题意

给出一个正\(n\)边形,问能否使用这\(n\)个点重新构成正\(m\)边形

题解

正多边形转正多边形,直接判断点能不能均分就好了

代码

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define def 110
using namespace std;
 
int main()
{   long _,n,m;
    for(scanf("%ld",&_);_;_--){
        scanf("%ld%ld",&n,&m);
        if(n%m==0)
            printf("YES\n");
        else
            printf("NO\n");
    }
    return 0;
}

B. Bogosort

题意

给出\(n\)个数,重新排列使得对于所有的\(i\)\(j\)\(a[i]-i\not= a[j]-j\)

题解

从大到小排个序,就能保证对于所有\(i<j\)\(a[i]>=a[j]\),从而\(a[i]-i>a[j]-j\)

代码

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define def 110
using namespace std;
 
long a[def];
 
int main()
{   long _,n,i,j;
    for(scanf("%ld",&_);_;_--){
        scanf("%ld",&n);
        for(i=1;i<=n;i++)
            scanf("%ld",&a[i]);
        sort(a+1,a+n+1,[&](long a,long b){return a>b;});
        for(i=1;i<=n;i++)
            printf("%ld ",a[i]);
        printf("\n");
    }
    return 0;
}

C. Adding Powers

题意

给出一串数和一个基数\(k\),每次可以选择一个数减去\(k^p(p>=0)\),求能否做到在每个p只用一次的情况下,将所有数都变为0

题解

因为每个\(p\)只能用一次,而且\(k^p>=k^{p-1}\),所以对每个数直接枚举\(p\)然后减去即可,过程中记录下p的使用记录,保证用过的不再使用

代码

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define ll long long
#define def 110
using namespace std;

bool b[def];

ll ksm(ll a,long b)
{
    if(!b)
        return 1;
    else
        if(b%2)
            return ksm(a*a,b/2)*a;
        else
            return ksm(a*a,b/2);
}

int main()
{    long _,n,m,i,j;
    ll maxx,x;
    bool t;
    for(scanf("%ld",&_);_;_--){
        scanf("%ld%ld",&n,&m);
        for(maxx=1;ksm(m,maxx)<=10000000000000000LL;maxx++);
        maxx--;
        t=true;
        memset(b,false,sizeof(b));
        for(i=1;i<=n;i++){
            scanf("%lld",&x);
            for(j=maxx;j>=0;j--)
                if(x>=ksm(m,j)&&!b[j]){
                    x-=ksm(m,j);
                    b[j]=true;
                }
            if(x)
                t=false;
        }
        if(t)
            printf("YES\n");
        else
            printf("NO\n");
    }
    return 0;
}

D. Count the Arrays

题意

构建长度为\(m\)的数列,其中每个数范围\([1,n]\),有且只有一对重复的数,并且可以构成“金字塔形”(先增后减),问这样的数列有多少种

题解

组合数问题,先在m个里选n-1个数;
然后在n-1个里挑一个来重复,因为挑出来的数中间一定得有比他大的数,所以,只有n-2种选择;
最后排列一下剩下的数,除了最大值,每个数都在最大值的左右二选一,所以是pow(2,n-3)
综上,答案就是\(C_m^{n-1}*(n-3)*pow(2,n-2)\)

代码

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define ll long long
#define MOD 998244353
#define def 200010
using namespace std;
 
ll jc[def],ny[def];
 
ll ksm(ll a,long b)
{
    if(!b)
        return 1;
    else
        if(b%2)
            return ksm(a*a%MOD,b/2)*a%MOD;
        else
            return ksm(a*a%MOD,b/2);
}
 
ll C(long n,long m)
{
    return jc[n]*ny[m]%MOD*ny[n-m]%MOD;
}
 
int main()
{   long n,m,i;
    ll ans=0;
    scanf("%ld%ld",&n,&m);
    jc[0]=1;
    ny[0]=ksm(jc[0],MOD-2);
    for(i=1;i<=m;i++){
        jc[i]=jc[i-1]*i%MOD;
        ny[i]=ksm(jc[i],MOD-2);
    }
    printf("%lld\n",C(m,n-1)*ksm(2,n-3)%MOD*(n-2)%MOD);
    return 0;
}

E. Array Shrinking

明天补题
loading……

Educational Codeforces Round 83 (Rated for Div. 2)

标签:记录   ++   mat   names   组合   ring   using   printf   math   

原文地址:https://www.cnblogs.com/2017py/p/12458773.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!