zoukankan      html  css  js  c++  java
  • Codeforces Round #224 (Div. 2) 题解

    C. Arithmetic Progression

        题意:有一列数,从小到大排列以后,你可以添加一个数,问你添加一个数以后,这个数列能不能变成等差数列,如果可以添加数,可以添加那几个

        思路:对于n==1|| n == 2的时候直接特判,对于大于2的情况,把数列排序以后,找到数组中相差最小的数作为公差,在此遍历有几个地方不满足,然后讨论

     代码:

    #include <bits/stdc++.h>
    using namespace std;
    
    const int maxn = 1e5 + 7;
    int a[maxn];
    int stk[maxn];
    int top ;
    int main()
    {
        int n;
        scanf("%d", &n);
        for(int i = 1; i <= n; i++) {
            scanf("%d", &a[i]);
        }
        sort(a + 1, a + 1 + n);
        if(n == 1){
            puts("-1");
            return 0;
        }
        if(a[1] == a[n]){
            printf("1
    ");
            printf("%d
    ",a[1]);
            return 0;
        }
        if(n == 2) {
            int len = a[2] - a[1];
            if(len % 2 == 0) {
                printf("3
    ");
                printf("%d %d %d
    ",a[1] - len, (a[1] + a[2]) / 2, a[2] + len);
            }
            else {
                printf("2
    ");
                printf("%d %d
    ",a[1] - len, a[2] + len);
            }
            return 0;
        }
        int minn = 0x3f3f3f3f;
        for(int i = 2; i <= n; i++) {
            minn = min(minn, a[i] - a[i - 1]);
        }
        top = 0;
        for(int i = 1; i < n; i++) {
            if(a[i] + minn == a[i + 1])continue;
            stk[++top] = i;
        }
        if(top > 1){
            puts("0");
        }
        else if(top == 0) {
            printf("2
    ");
            printf("%d %d
    ",a[1] - minn, a[n] + minn);
        }
        else {
            if(a[stk[1]] + 2 * minn == a[stk[1] + 1]){
                printf("1
    ");
                printf("%d
    ",a[stk[1]] + minn);
            }
            else {
                printf("0
    ");
            }
        }
        return 0;
    }
    View Code

    D. Ksenia and Pawns

        题意:有一张n*m的地图(2000)只有><^v# 5 中符号,#的位置可以放两个棋子,#上的棋子都不可以移动,其他符号上的棋子可以按照方向移动一格,现在你有两个棋子,问最多两个棋子可以一共移动多少步

        思路:枚举每个#作为两颗棋子最后的终点,反向向回推,维护每天路的最大值,以及全局的最大值和次大值,如果全局最大值和次大值相等,答案就是二倍的最大值,否则答案是最大值*2 – 1,即放两个相邻的棋子,走到最后

        代码:

    #include <bits/stdc++.h>
    using namespace std;
    
    const int maxn = 2007;
    int n, m;
    char mp[maxn][maxn];
    
    int max1, max2;
    int cnt;
    int dx[10] = {0, 0, 1, -1};
    int dy[10] = {-1, 1, 0, 0};
    char s[10] = {'>', '<', '^', 'v'};
    
    void Max(int x)
    {
        if(x > max1) {
            max1 = x;
        }
        else if(x > max2) {
            max2 = x;
        }
    }
    int dfs(int x, int y)
    {
        int ans = 0;
        cnt ++;
        for(int i = 0; i < 4; i++) {
            int xx = dx[i] + x, yy = dy[i] + y;
            if(xx < 1 || xx > n || yy < 1 || yy > m || (mp[xx][yy] != s[i]))continue;
            if(mp[x][y] == '#') Max(dfs(xx, yy));
            else ans = max(ans, dfs(xx, yy));
        }
        return ans + 1;
    }
    int main()
    {
        scanf("%d%d%", &n, &m);
        for(int i = 1;i <= n; i++) {
            for(int j = 1; j <= m; j++) {
                cin >> mp[i][j];
            }
        }
        max1 = 0, max2 = 0;
        cnt = 0;
        for(int i = 1; i <= n; i++) {
            for(int j = 1; j <= m; j++) {
                if(mp[i][j] == '#') {
                    dfs(i, j);
                }
            }
        }
        if(cnt < n * m) {
            puts("-1");
        }
        else {
            printf("%d
    ",max1 == max2 ? max1 * 2: max1 * 2 - 1);
        }
        return 0;
    }
    View Code

    E. Ksenia and Combinatorics

        题意:有n(50)个点,让你构造出一个树满足下列条件,

    1有n个点,标号为1~n

    2根的度数最多为2,除了根之外的点的度数最多为3

    3树的最大匹配数不超过k

    问能构造出多少颗,答案对1e9+7取模

        思路:定义dp[i][j][0|1]表示用i个点,构造最大匹配数为j的dp[i][j][0]表示没有子节点连接根,[1]表示有子节点连接根,然后枚举树的左节点个数和右节点个数,以及左右节点是否是连接根的

        dp[i][j][0] += dp[l][k][1] * dp[r][j – k][1] * res

        dp[i][j][1] += dp[l][k][1] * dp[r][j – k -1] [0]* res

        dp[i][j][1] += dp[l][k][0] * dp[r][j – k -1] [1]* res

        dp[i][j][1] += dp[l][k][0] * dp[r][j – k -1] [0]* res

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    
    typedef long long LL;
    const int maxn = 57;
    const int MOD = 1e9 + 7;
    const int inv2 = 500000004;
    int c[maxn][maxn];
    int n, k;
    LL dp[maxn][maxn][2];
    
    LL mod(LL x)
    {
        if(x >= MOD) return x % MOD;
        return x;
    }
    int main()
    {
        c[0][0] = 1;
        for(int i = 1; i <= 50; i++) {
            c[i][0] = c[i][i] = 1;
            for(int j = 1; j < i; j++) {
                c[i][j] = mod(c[i - 1][j - 1] + c[i - 1][j]);
            }
        }
        scanf("%d%d", &n, &k);
        if(k > n/2){
            printf("0
    ");
            return 0;
        }
        dp[1][0][0] = dp[0][0][1] = 1;
        for(int i = 1; i <= n; i++) {
            for(int j = 0; j <= k; j++) {
                for(int l = 0,r = i - 1; l <= r; l++, r--) {
                    for(int k = 0; k <= j; k++) {
                        LL res = 1;
                        res = c[i - 1][l];
                        if(l == r) res = mod(res * inv2);
                        if(l) res = mod(mod(res * l) * r);
                        else res = mod(res * r);
                        dp[i][j][0] = mod(dp[i][j][0] + mod(mod(dp[l][k][1] * dp[r][j - k][1]) * res));
                        if(k < j) {
                            dp[i][j][1] = mod(dp[i][j][1] + mod(mod(dp[l][k][1] * dp[r][j - k - 1][0]) * res));
                            dp[i][j][1] = mod(dp[i][j][1] + mod(mod(dp[l][k][0] * dp[r][j - k - 1][1]) * res));
                            dp[i][j][1] = mod(dp[i][j][1] + mod(mod(dp[l][k][0] * dp[r][j - k - 1][0]) * res));
                        }
                    }
                }
            }
        }
        printf("%d
    ",mod(dp[n][k][0] + dp[n][k][1]));
        return 0;
    }
    View Code
  • 相关阅读:
    ConcurrentDictionary内部机制粗解
    c# class struct区别
    virtualbox安装增强功能时【未能加载虚拟光盘】
    【C++】 友元函数friend
    C++命名空间(namespace)(转载)
    C++中memset()用法
    C++ 虚函数和纯虚函数的区别
    C++中栈和堆上建立对象的区别(转载)
    c++继承
    C++构造函数和析构函数
  • 原文地址:https://www.cnblogs.com/lalalatianlalu/p/10417888.html
Copyright © 2011-2022 走看看