【解题报告】 Educational Codeforces Round 40

题目链接


A. Diagonal Walking(Codeforces 954A)

题意

给出一个仅含 R R U 的字符串。问如何进行一系列操作(每次操作可以将连续的 RU R U UR U R 替换 D D ),使得最后得到的字符串长度最小。

思路

本题的入手点是,先贪心地提出一个算法,再看看有没有更优的算法。
显然,我们可以提出这样的贪心算法:从左到右依次考虑字符串 s 中相邻的字符对,一旦出现 RU R U 或者 UR U R 的组合就将其替换成 D D
那么,这个算法对不对呢?假如我们不这么贪心(看见可以替换的就立即替换),是否会有更优解?设字符串 s =" R U R . . . . . . . " ,其中省略号表示任意长度的任意字符。我们从左到右依次考虑相邻的字符对,第一个字符对是 RU R U ,如果我不立即将 RU R U 替换成 D D ,而把 U 留给右侧的 R R ,那么结果也没有更优,反倒是 U U U 右侧的 R 丧失了脱单机会。所以,不贪心是不会得到更好的解的。

代码

#include <bits/stdc++.h>
using namespace std;

string s;
int n, cnt;

// 判断是否需要替换
bool ok(int i) {
    if(s[i] == 'R' && s[i + 1] == 'U') {
        return true;
    }
    if(s[i] == 'U' && s[i + 1] == 'R') {
        return true;
    }
    return false;
}

int main() {
    ios::sync_with_stdio(false);
    cout.tie(0);
    cin.tie(0);
    cin >> n >> s;
    // 枚举相邻字符对
    for(int i = 0; i < n - 1; i++) {
        if(ok(i)) {
            cnt ++;
            i ++;
        }
    }
    cout << n - cnt << endl;
    return 0;
}

B. String Typing(Codeforces 954B)

题意

我们将字符串 s s 打印到屏幕上。也就是说,初始状态屏幕上有一个空串 t 。然后每次执行以下两种操作中的一种。
- 在 t t 的尾部加入某个小写英文字母
- 将 t 拷贝一个副本 p p ,将 p 加入 t t 的末尾(最多只能做一次)
给定 s ,求完成目标的最少操作数。

思路

本题的入手点在于,将问题转化为决策问题。
这个问题本质上是决策问题。正如题目介绍,我们最多可以做一次拷贝操作。这个操作完成后可能会有最优解,也可能没有。因此我们要考虑是否要做这个操作,以及这个操作在什么时候做。这就是个决策问题了,考虑到数据规模不是很大,枚举即可。
假设我们在 t t 的长度已经为 i 的情况下做拷贝操作(此时t的各个字符是确定的,因为在拷贝之前只能做第一种操作)。如果此时做拷贝操作合法(不会得到不是 s s 的字符串),那么我们可以用 O ( 1 ) 的复杂度算出操作数,从而更新最优解。所以要求最优解就要枚举 i i 。注意,最优解的初始值应该是 s 的长度,对应不做拷贝操作的情况。
算法整体的时间复杂度为 O(n2) O ( n 2 ) 。(除了枚举 i i O ( n ) 复杂度外,判断拷贝是否合法还需要 O(n) O ( n ) 的复杂度)

代码

#include <bits/stdc++.h>
using namespace std;

string s;
int n, ans;

int main() {
    ios::sync_with_stdio(false);
    cout.tie(0);
    cin.tie(0);
    cin >> n >> s;
    ans = n;
    // 枚举在已经打印了多少字符的情况下做拷贝操作
    for(int i = 0; i < n / 2; i++) {
        if(s.substr(0, i + 1) == s.substr(i + 1, i + 1)) {
            ans = min(ans, (i + 1) + 1 + n - 2 * (i + 1));
        }
    }
    cout << ans << endl;
    return 0;
}

C. Matrix Walk(Codeforces 954C)

题意

有一个 x×y x × y 的矩阵,矩阵的数是按照电话按键的方式排列的。现在主角从矩阵某个位置开始连续走 n n 步(每步只能向上下左右四个方向走)。将经过的矩阵元素记录下来形成一个序列 a 。现在给出这个 n n 和这个序列 a ,问可能的 x x y 是多少。

思路

本题的入手点在于按照先特殊后一般的顺序思考问题。
首先,假设矩阵只有一行。那么主角一定只能左右走。也就是说,序列中的数都是连续变化的。只会从元素 3 3 走到元素 4 ,从元素 15 15 走到元素 14 14 ,不会从元素 15 15 走到元素

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值