A.小红的环形字符串
A-小红的环形字符串_牛客周赛 Round 2 (nowcoder.com)
题目:
小红拿到了一个环形字符串s。所谓环形字符串,指首尾相接的字符串。
小红想顺时针截取其中一段连续子串正好等于t,一共有多少种截法?
思路:构造个循环数组然后再用双指针判断。
代码:
#include <iostream>
using namespace std;
int main()
{
string s1, s2;
cin >> s1 >> s2;
int res = 0;
int n = s1.size();
for(int i = 0; i < n; i++){
int k = 0;
while(k < s2.size() && s1[(i + k) % n] == s2[k]){
k++;
}
if(k == s2.size()){
res++;
}
}
cout << res <<endl;
return 0;
}
B.相邻不同数字的标记
B-相邻不同数字的标记_牛客周赛 Round 2 (nowcoder.com)
题目:
小红拿到了一个数组,每个数字被染成了红色或蓝色。
小红有很多次操作,每次操作可以选择两个相邻的不同颜色的数字标记,并获得它们数字之和的得分。已经被标记的数字无法再次标记。
小红想知道,自己最多能获得多少分。
思路:题目上给出可以选择两个相邻不同颜色且都没有被标记的数字进行相加。这里就出现了一个问题:如果出现RBR时,我们如果选择了前面的RB,那么后面的BR就选不了了。这里就要进行讨论了。当前操作会影响下一步的操作。所以我们可以选择用动态规划来求最大值。
dp[ i ]:在i的位置上小红所能获得的最大的分数。
当i与i - 1颜色不同时:
选i:dp[ i ] = dp[i - 2] + a[i - 1] + a[ i ];
不选i:dp[ i ] = dp[i - 1];
在之间选最大值即可。
代码:
#include <iostream>
using namespace std;
const int N = 1e5 + 10;
string s, tmp = " ";
int a[N];
long long dp[N];
int main()
{
int n;
cin >> n;
for (int i = 1; i <= n; i++) cin >> a[i];
cin >> s;
s = tmp + s;
for (int i = 2; i <= n; i++) {
if (s[i] != s[i - 1]) {
dp[i] = max(dp[i - 1], dp[i - 2] + a[i] + a[i - 1]);
}
else{
dp[i] = dp[i - 1];
}
}
cout << dp[n] << endl;
return 0;
}
C.小红的俄罗斯方块
C-小红的俄罗斯方块_牛客周赛 Round 2 (nowcoder.com)
题目:
思路:俄罗斯方块我们都玩过,情况也就是遇到格子就停下来。图形的哪个地方先遇到格子,整个图形就会在那个地方停下来。所以我们分情况讨论,然后比较整个图形所占有的每一列的格子最大值,接着更新相应列的格子高度即可。
代码:
#include <iostream>
#include <algorithm>
using namespace std;
int h[9];
int main()
{
int n;
cin >> n;
for(int i = 0; i < n; i++){
int a, j;
cin >> a >> j;
if(a == 0){
int x = max(h[j], h[j + 1]);
h[j + 1] = x + 1;
h[j] = x + 3;
}
if(a == 90){
int x = max(h[j] + 1, h[j + 1]);
x = max(x, h[j + 2]);
h[j] = x + 1;
h[j + 1] = x + 1;
h[j + 2] = x + 1;
}
if(a == 180){
int x = max(h[j], h[j + 1] + 2);
h[j] = x + 1;
h[j + 1] = x + 1;
}
if(a == 270){
int x = max(h[j], h[j + 1]);
x = max(x, h[j + 2]);
h[j] = x + 1;
h[j + 1] = x + 1;
h[j + 2] = x + 2;
}
}
for(int i = 1; i <= 8; i++) cout << h[i] << ' ';
return 0;
}