ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【题解】Educational Codeforces Round 83(CF1312)

2022-07-28 07:31:30  阅读:140  来源: 互联网

标签:Educational int 题解 Codeforces cin MAXN freopen printf dp


A.Two Regular Polygons

假设构造多边形的边数为 \(n\),给定多边形的边数为 \(m\),若顶点完全覆盖也就意味着给定的多边形可以被平均分成 \(n\) 份,也就是 \(m\) 是 \(n\) 的倍数

点击查看代码
#include<bits/stdc++.h>
using namespace std;
int main(){
    int t;
    cin>>t;
    while(t--){
        int x,y;
        cin>>x>>y;
        if(x % y == 0)
            printf("YES\n");
        else
            printf("NO\n");
    }
    return 0;
}

B.Bogosort

不好分析所以只能显然了:把 \(a\) 从大到小排序。
考虑原式的变形:

\[j-i \not= a_j - a_i \]

这样就可以使得 \(j-i\) 一定为正数,而 \(a_j - a_i\) 是一个小于等于 \(0\) 的数,所以一定不等。

点击查看代码
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 105;
int a[MAXN];
int main(){
    // freopen("in.txt","r",stdin);
    // freopen("out.txt","w",stdout);
    int t;
    cin>>t;
    while(t--){
        int n;
        cin>>n;
        for(int i=1; i<=n; i++){
            cin>>a[i];
        }
        sort(a+1,a+n+1);
        for(int i=n; i>=1; i--){
            printf("%d ",a[i]);
        }
        printf("\n");
    }
    return 0;
}

C.Adding Powers

看见 \(k^i\) 就联想到 \(k\) 进制,也就是说我们在 \(k\) 进制下每一位只能加一次,那么我们就把 \(a\) 按 \(k\) 进制拆开,如果每一位最多只需要一个那么就合法,否则就不合法。

点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int MAXN = 100;
int n,k,cnt[MAXN],a[MAXN];
bool flag = true;
void fenjie(int x){
    for(int i=1; i<=64; i++){  //log 也就这么大了
        cnt[i]+=x%k;
        if(cnt[i] >= 2) flag = false;
        x /= k;
    }
    if(x)   flag = false;
}
signed main(){
    // freopen("in.txt","r",stdin);
    // freopen("out.txt","w",stdout);
    int t;
    cin>>t;
    while(t--){
        memset(cnt,false,sizeof(cnt));
        flag = true;
        cin>>n>>k;
        for(int i=1; i<=n; i++){
            cin>>a[i];
            fenjie(a[i]);
        }
        if(flag)    printf("YES\n");
        else    printf("NO\n");
    }
    return 0;
}

D.Count the Arrays

很明显就是一个推式子的题。
我们要从这 \(m\) 个数里选出 \(n-1\) 个数,使得他们分布在最大值的左边或右边,并且有一个数是左右都有的,也就是重复的,所以答案就是

\[2^{n-3}\times \binom{m}{n-1} \times (n-2) \]

第一项:选左边或右边。第二项:选 \(n-1\) 个数。第三项:选哪个数重复。

点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int MOD = 998244353;
const int MAXN = 2e5+5;
int pre[MAXN];
int power(int a,int b){
    int res = 1;
    while(b){
        if(b & 1)   res = (res * a) % MOD;
        a = (a * a) % MOD;
        b >>= 1;
    }
    return res;
}
signed main(){
    int n,m;
    cin>>n>>m;
    if(n == 2)  printf("0\n");
    else{
        pre[1] = 1;
        for(int i=2; i<=m; i++)
            pre[i] = (pre[i-1] * i)%MOD;
        printf("%lld\n",((((power(2,n-3) * (n-2))%MOD * pre[m])%MOD * power(pre[n-1],MOD-2))%MOD * power(pre[m - n + 1],MOD-2))%MOD);
    }
    return 0;
}

E.Array Shrinking

看到 \(n \le 500\) 以及这种题面显然就可以想到区间 \(\text{DP}\)。状态也非常显然:\(dp[l][r]\) 代表将 \([l,r]\) 最短的合并后的长度。
转移也十分显然:

\[dp[l][r] = \min_{mid = l}^{r-1}(dp[l][mid] + dp[mid+1][r]) \]

需要注意的是:如果两个区间都可以合并为一个数,并且这一个数相同,那么我们就可以合并这两个区间,具体来说就是记 \(w[l][r]\) 表示 \([l,r]\) 如果可以合并为一个数,这个数是谁。

点击查看代码
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 505;
int dp[MAXN][MAXN],w[MAXN][MAXN],a[MAXN];
int main(){
    memset(dp,0x3f,sizeof(dp));
    // freopen("in.txt","r",stdin);
    // freopen("out.txt","w",stdout);
    int n;
    cin>>n;
    for(int i=1; i<=n; i++){
        cin>>a[i];
        dp[i][i] = 1;w[i][i] = a[i]; 
    }
    for(int len=2; len<=n; len++){
        for(int l=1; l + len - 1 <= n; l++){
            int r = l + len - 1;
            for(int k=l; k<r; k++){
                dp[l][r] = min(dp[l][r],dp[l][k]+dp[k+1][r]);
                if(w[l][k] == w[k+1][r] && dp[l][k] == 1 && dp[k+1][r] == 1){
                    dp[l][r] = 1;w[l][r] = w[l][k] + 1;
                }
            }
        }
    }
    printf("%d\n",dp[1][n]);
    return 0;
}

标签:Educational,int,题解,Codeforces,cin,MAXN,freopen,printf,dp
来源: https://www.cnblogs.com/linyihdfj/p/16527185.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有