牛客练习赛60补题

A.https://ac.nowcoder.com/acm/contest/4853/A

在这里插入图片描述

思路:考虑位运算&的特性 只有两者都为1才会对答案有贡献 且 对答案贡献的值为 1 << k 其中k是当前1所在二进制下的位数 所以考虑预处理每一个位的1出现的次数 其中对每一位都会遍历n*n次 所以每一位对答案的贡献就是 a[i]a[i](1 << i) a[i]为当前位置1的个数

#include <bits/stdc++.h>

using namespace std;

#define LL long long

int main()
{
    int n;

    cin >> n;

    LL a[35] = {0};

    for(int i = 0;i < n;i ++)
    {
        int x;
        cin >> x;

        int k  = 0;

        while(x)
        {
            a[k ++] += x%2 ;
            x /= 2;
        }
    }

    LL sum = 0;

    for(int i = 0;i <= 32;i ++)
    {
        sum += a[i]*a[i]*(1<<i);
    }

    printf("%lld\n",sum);

    return 0;
}

B.https://ac.nowcoder.com/acm/contest/4853/B

题意:给出n个点 用这n个点构造三角形 问这些三角形的周长是多少 数据保证合法
思路:我们从边考虑 组成一个三角形需要三条边 且 必须要三条边 所以每条边只能被选 n - 2次 所以每条边对答案的贡献 就是曼哈顿距离* 出现的次数为n-2次 然后暴力计算和即可 记得开LL

#include <bits/stdc++.h>

using namespace std;

#define LL long long

const int mod = 998244353;

LL a[3005][2];

int main()
{
    int n;

    cin >> n;

    for(int i = 0;i < n;i ++)
    {
        cin >> a[i][0] >> a[i][1];
    }

    LL sum = 0;

    for(int i = 0;i < n - 1;i ++)
    {
        for(int j = i + 1;j < n;j ++)
        {
            sum += (((abs(a[i][0] - a[j][0])) + abs(a[i][1] - a[j][1]))*(n - 2))%mod;
            sum %= mod;
        }
    }

    printf("%lld\n",sum%mod);

    return 0;
}

C.https://ac.nowcoder.com/acm/contest/4853/C

题意:给出长度为n的字符串 求有少长度为k的不同子序列
思路:dp肯定是没跑了 用i, j , k 来表示 前i个字符 长度为j 以字符’a’ + k结尾的子串 dp的值为字符串的数量

如果s[i] == ‘a’ + k 则构造出新的字符串 否则 则从上个状态转移过来

#include <bits/stdc++.h>

using namespace std;

#define LL long long

const int mod = 1e9 + 7,N = 1e3 + 5;

LL dp[N][N][30];///前i个字符 长度为j的 以'a' + k 为结尾的字符串

int main()
{
    int n , m;
    string s;

    cin >> n >> m ;

    cin >> s;

    if(!m)
    {
        cout << 1;
        return 0;
    }

    for(int i = 1;i <= n;i ++)
    {
        dp[i][1][s[i - 1] - 'a'] = 1;

        for(int j = 1;j <= m;j ++)
        {
            for(int k = 0;k < 26;k ++)
            {
                if(s[i - 1] - 'a' == k)
                {
                    for(int kk = 0; kk < 26 ;kk ++)
                    {
                        dp[i][j][k] += dp[i - 1][j - 1][kk];
                        dp[i][j][k] %= mod;
                    }
                }
                else
                {
                    dp[i][j][k] += dp[i - 1][j][k];
                    dp[i][j][k] %= mod;
                }
            }
        }
    }

    LL res = 0;

    for(int i = 0;i < 26;i ++)
        res += dp[n][m][i],res %= mod;

    printf("%lld\n",res);

    return 0;
}

D.待补

发布了57 篇原创文章 · 获赞 0 · 访问量 1711

猜你喜欢

转载自blog.csdn.net/weixin_44144278/article/details/105176263