【解题报告】Codeforces Round #301 (Div. 2)

这篇博客是关于Codeforces Round #301 (Div. 2)的比赛解题报告,详细分析了A到E五道题目。题目包括Combination Lock、School Marks、Ice Cave、Bad Luck Island和Infinite Inversions。解题思路涵盖了不同的算法,如模拟、搜索(DFS、BFS)、动态规划和树状数组,还提供了相应的代码实现。
摘要由CSDN通过智能技术生成

题目链接


A.Combination Lock(Codefoeces 540A)

思路

由于锁的齿轮的数量比较少,所以可以对每个齿轮,尝试向上拨或向下拨两种方法来更新最小转动次数。具体可以用模10下的加减法来实现。

代码

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

int n, a, b, ans;
string s, t;

int main() {
    scanf("%d", &n);
    cin >> s >> t;
    ans = 0;
    for(int i = 0; i < n; i++) {
        a = (s[i] - t[i] + 10) % 10;
        b = (t[i] - s[i] + 10) % 10;
        ans += min(a, b);
    }
    printf("%d\n", ans);
    return 0;
}

B.School Marks(Codeforces 540B)

分析

可以从题目中抽取出主角分数的三个限制条件:

  • 每场考试的分数都在 1 p 分之间
  • 考试的分数至少以 y 作为中位数
  • 考试的总分不得超过 x

于是可以想到的一种可行的策略是:当考低分段(小于中位数)的分数的次数比较多的时候考 y 分,当考高分段(大于或等于中位数)的分数的次数比较多的时候考 1 分。这样就能够在满足前两种情况的前提下,拿到可能拿到的最低分。此时若能够满足第三种条件,那么就构造出了一种可行解。若不能满足第三种条件的话无论如何都不能构造出可行解了。

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

const int maxn = 1e3;
int n, p, k, x, y, low, high, mark, sum, ans[maxn];

int main() {
    cin >> n >> k >> p >> x >> y;
    low = high = sum = 0;
    for(int i = 0; i < k; i++) {
        cin >> mark;
        sum += mark;
        if(mark < y) low++;
        else high++;
    }
    for(int i = 0; i < n - k; i++) {
        if(low >= high) {
            ans[i] = y;
            sum += y;
            high++;
        }
        else {
            ans[i] = 1;
            sum++;
            low++;
        }
    }
    if(low < high && sum <= x) {
        for(int i = 0; i < n - k; i++) {
            printf("%d ", ans[i]);
        }
        puts("");
    }
    else puts("-1");
    return 0;
}

C.Ice Cave(Codeforces 540C)

思路

典型的路径寻找问题。用搜索来解决。注意如果用DFS来解决的话不用保护现场,因为被破坏的现场有“记忆”功能,能够减少很多枚举量。若保护现场则复杂度变成指数级别,提交会超时。

代码(DFS)
#include <bits/stdc++.h>
using namespace std;

const int maxn = 505;
char G[maxn][maxn];
int n, m, r1, c1, r2, c2;
int dx[] = {-1, 1, 0, 0};
int dy[] = {
  0, 0, -1, 1};

bool dfs(int x, int y) {
    if(G[x][y] != '.') {
        return x == r2 && y == c2;
    }
    G[x][y] = 'X';
    for
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值