牛客练习赛53(待更新)
题目链接:Link
A 超越学姐爱字符串
题意: 长度为N的字符串,只能有C,Y字符,且字符串中不能连续出现 C。
思路: 其实就是DP,\(Dp[i][c]\) 表示长度为 \(i\) , 以 \(C\) 结尾的字符串有多少种。那么整个状态方程就有:
\[ DP[i][c] = Dp[i-1][y]\\Dp[i][y] = Dp[i-1][c] + Dp[i-1][y] \]
会发现其实就是斐波那契数列而已。
Code:
#include
using namespace std;
typedef unsigned long long ULL;
const ULL MOD = 1000000000 + 7;
const int maxn = 100000 + 13;
ULL Dp[maxn][2];
void Init() {
// 0 --> Y, 1 ---> C
memset(Dp, 0, sizeof(Dp));
Dp[0][0] = Dp[0][1] = 0;
Dp[1][0] = Dp[1][1] = 1;
for(int i = 2; i < maxn; ++i) {
Dp[i][0] = (Dp[i-1][0] + Dp[i-1][1]) % MOD;
Dp[i][1] = Dp[i-1][0];
}
}
int main() {
Init();
int n;
while(scanf("%d", &n) != EOF) {
ULL sum = (Dp[n][0] + Dp[n][1]) % MOD;
printf("%lld\n", sum);
}
return 0;
}
B 美味果冻
题意: $ \sum_{i=1}^{n}\sum_{j=1}^{i} {i * [\frac{i}{j}]^{j}}$ 简单暴力的题意。。。
思路:这题就是找规律。。。把具体计算式写出来,就发现规律了。具体如下:
\[ \begin{align}&1 \\&2^2 \ \ 2*1^2 \\&3^2 \ \ 3*1^2 \ \ 3*1^3 \\&4^2 \ \ 4*2^2 \ \ 4*1^3 \ \ 4*1^4\\&\cdots \\&n^2 \ \ n*[\frac{n}{2}]^2 \ \ n*[\frac{n}{3}]^3 \cdots n*1^n\end{align} \]
第一列即为 \(\sum_i^n i^2\) ,第\(J\)列开始,就是以 \([\frac{n}{j}]\) 分块了。
Code:
int main() {
false_stdio;
cin >> n;
for (ll j = 1; j <= n; j++) {
num[j] = j;
ans = (ans + j * j % mod) % mod;
}
for (ll j = 2; j <= n; j++) {
cnt = n / j;
ll L = j;
for (int i = 1; i < cnt; i++) {
tot = (L * j + (j * (j - 1) >>1)) % mod;
num[i] = num[i] * i % mod;
ans = ans + tot * num[i] % mod;
L += j;
}
num[cnt] = num[cnt] * cnt % mod;
tot = (n - cnt * j + 1) % mod;
ans =ans+ (L * tot % mod + (tot * (tot - 1)>>1)) % mod * num[cnt] % mod;
}
ans = (ans + mod) % mod;
cout << ans << endl;
return 0;
}
富豪凯匹配串
题意:0-1 字符串匹配, '_' 代表通配符,输出有多少是成功匹配的。
思路:因为是 0-1 字符串,所以是可以使用 bitset 来做这题的。按与操作来匹配相应位是否相等即可。
Code:
int cnt = 0;
bitset<1005> p;
bitset<1005> q;
cin >> str;
for(int j = 0; j < m; ++j) {
char c = str[j];
if(c == '0') {
q[j] = 0; p[j] = 1;
} else if(c == '1') {
p[j] = q[j] = 1;
} else if(c == '_') {
p[j] = q[j] = 0;
}
}
for(int i = 0; i < n; ++i) {
if((p&Str[i]) == q) cnt ++;
}
cout << cnt << endl;