题目解析 小U和字符‘R‘的喜好 | 豆包MarsCode AI刷题

151 阅读4分钟

题目

问题描述:

小U非常喜欢字符'R',并且定义字符串的权值为字符'R'的出现次数。现在她手上有一个长度为nn的字符串s,由字符'R''B'组成。她想知道,在所有长度为nn、仅由字符'R''B'组成的字符串中,字典序不小于字符串s的字符串的权值之和是多少。由于结果可能很大,答案需要对109+7109+7取模。

例如,字符串"RRBRB"的权值为 3,因为其中包含 3 个字符'R'

样例如图:

{CFE03159-AFF7-4E91-BA38-33A32B5602DF}.png 先总览代码

{F71C5B22-6010-49AA-B247-7F53CB51C8CB}.png

我尽量详细解释:看到第一行:#include <bits/stdc++.h>

这是一个在某些编译器(尤其是GCC和Clang)中可用的头文件,它是一个包含了几乎所有标准库头文件的单行包含指令。这个头文件并不是C++标准的一部分,而是GCC编译器的一个扩展,用于方便开发者快速包含所有常用的标准库头文件。

1.计数函数:

{D552B856-A9A0-4204-BCCB-C570934A6E49}.png 这段代码定义了一个名为 countBits 的函数,它接受一个整数 n 作为参数,并返回一个整数。这个函数的目的是计算从1到 n 所有整数的二进制表示中1的总数。

下面是代码的逐行解释:

  1. int countBits(int n) {:定义了一个名为 countBits 的函数,它返回一个整数,并且接受一个整数 n 作为参数。

  2. vector<int> dp(n + 1, 0);:定义了一个动态数组(向量)dp,大小为 n + 1,所有元素初始化为0。这个数组将用于存储从1到 i 的所有整数的二进制表示中1的总数。

  3. for (int i = 1; i <= n; ++i) {:开始一个循环,从1开始,直到 n

  4. dp[i] = dp[i >> 1] + (i & 1);:对于每个 i,计算其二进制表示中1的个数。这里使用了两个技巧:

    • i >> 1:将 i 右移一位,相当于除以2,用于递归地计算 i/2 的二进制中1的个数。
    • i & 1:将 i 与1进行按位与操作,如果 i 是奇数,结果为1,否则为0。这用于计算 i 本身的最低位是否为1。
  5. int sum = 0;:定义了一个整数变量 sum 并初始化为0,用于存储从1到 n 所有整数的二进制表示中1的总数。

  6. for (int i = 1; i <= n; ++i) {:开始另一个循环,从1开始,直到 n

  7. sum += dp[i];:将 dp[i] 的值加到 sum 上,累加每个整数的二进制表示中1的个数。

  8. // cout<<n<<" "<<sum<<endl;:这是一个注释掉的代码行,如果取消注释,它将打印出 nsum 的值,用于调试。

  9. return sum;:函数返回 sum,即从1到 n 所有整数的二进制表示中1的总数。

  10. }:结束函数定义。

这个函数使用了动态规划(DP)的思想,通过递归地计算每个整数的二进制表示中1的个数,并将结果存储在 dp 数组中,从而避免了重复计算。这种方法的时间复杂度是O(n),因为每个整数只计算一次。

2. solution 函数

{B0B3CB4A-0C67-4251-AE38-B465247AB241}.png 它接受两个参数:一个整数 n 和一个字符串 s。函数的目的是根据字符串 s 中的字符 'R' 来计算一个特定的值。

下面是代码的逐行解释:

  1. int solution(int n, string s) {:定义了一个名为 solution 的函数,它返回一个整数,并且接受两个参数:一个整数 n 和一个字符串 s
  2. // write code here:这是一个注释,提示开发者在这里编写代码。
  3. int num = 0;:定义了一个整数变量 num 并初始化为0。
  4. for (int i = 0; i < n; i++) {:开始一个循环,从0开始,直到小于 n(字符串 s 的长度)。
  5. num *= 2;:在每次循环中,将 num 的值乘以2。
  6. if (s[i] == 'R') {:检查字符串 s 中当前索引 i 的字符是否为 'R'。
  7. num += 1;:如果当前字符是 'R',则将 num 的值增加1。
  8. }:结束 if 语句和 for 循环。
  9. return countBits((1 << n) - 1) - countBits(num - 1);:函数返回两个 countBits 函数调用的结果之差。countBits 函数(未在代码中定义)可能是用来计算一个整数的二进制表示中1的个数。这里计算的是 (1 << n) - 1(即 n 位全为1的二进制数)的二进制中1的个数减去 num - 1 的二进制中1的个数。