优快云竞赛第49期题解

  优快云编程竞赛报名地址:https://edu.youkuaiyun.com/contest/detail/46

1. 题目名称:隧道逃生 

小海豚喜欢打游戏,现在它在操纵游戏人物小C逃脱废弃的隧道,逃生装置在小C的前方 X 米远的位置。但是游戏机只有两个按钮:前进和后退,按前进,小C会前进 m 米,按后退,小C会后退 n 米。 小海豚必须设法把小C送到逃生装置上, 方能逃离隧道,请你帮帮小海豚,告诉它至少要操作多少次,才能通关。 

        图方便直接模拟。

#include <bits/stdc++.h>
using namespace std;
int main()
{
    int X, m, n;
    cin >> X >> m >> n;
    int sum = X / m + (X % m > 0), now = sum * m;
    while (now % n != X % n)
        now += m, ++sum;
    sum += (now - X) / n;
    cout << sum << endl;
    return 0;
}

 

 2. 题目名称:小艺照镜子

已知字符串str。 输出字符串str中最长回文串的长度。 

        暴力或者Manacher算法。

#include <bits/stdc++.h>
using namespace std;
int main()
{
    string s;
    cin >> s;
    int n = s.size(), ans = 0;
    for (int i = 0; i < n; ++i)
    {
        int j = 1;
        for (; i - j >= 0 && i + j < n; ++j)
        {
            if (s[i - j] != s[i + j])
                break;
        }
        --j;
        ans = max(ans, j * 2 + 1);
        for (j = 0; i - j >= 0 && i + 1 + j < n; ++j)
        {
            if (s[i - j] != s[i + 1 + j])
                break;
        }
        ans = max(ans, j * 2);
    }
    cout << ans << endl;
    return 0;
}

 

 3. 题目名称:大整数替换数位

以字符串的形式给你一个长度为 M 的整数 N,请你计算出对这个数进行一次操作后模 9 的值为 1 的所有可能的不同操作 方式。 在一次操作中, 我们可以选择 N 的一个数位 N[i],并把它替换成另一个不同的 0 到 9 范围之内的数 B,两种操作方式不同当且仅当它们选择的 i 或 B 不同。 

        10进制下模9为1只跟数位本身有关,故枚举所有情况即可。

#include <bits/stdc++.h>
using namespace std;
const int maxn = 100010;
char a[maxn];
int main()
{
    int n, ans = 0, sum = 0;
    cin >> n >> a;
    for (int i = 0; i < n; ++i)
        sum = (sum + a[i] - '0') % 9;
    for (int i = 0; i < n; ++i)
    {
        for (int j = 0; j < 10; ++j)
        {
            if (a[i] - '0' == j)
                continue;
            if ((sum - (a[i] - '0') + j + 9) % 9 == 1)
                ++ans;
        }
    }
    cout << ans << endl;
    return 0;
}

 

4. 题目名称:清理磁盘空间 

小明电脑空间满了,决定清空间。为了简化问题,小明列了他个人文件夹(/data)中所有末级文件路径和大小,挑选出总 大小为 m 的删除方案,求所有删除方案中,删除操作次数最小是多少。 一次删除操作:删除文件或者删除文件夹。如果删除文件夹,那么该文件夹包含的文件都将被删除。 文件夹的大小:文件夹中所有末级文件大小之和 

        我的做法是建树,然后树上背包。 

#include <bits/stdc++.h>
using namespace std;
const int maxn = 2010;
const int INF = 0x3f3f3f3f;
unordered_map<string, int> id;
vector<int> G[maxn];
int tot, n, m, w[maxn], dp[maxn][1010];
void dfs(int u)
{
    memset(dp[u], 0x3f, sizeof(dp[u]));
    dp[u][0] = 0;
    sort(G[u].begin(), G[u].end());
    G[u].erase(unique(G[u].begin(), G[u].end()), G[u].end());
    for (int v : G[u])
    {
        dfs(v);
        w[u] += w[v];
        for (int i = min(m, w[u]); i >= 0; --i)
        {
            for (int j = min(i, w[v]); j; --j)
            {
                dp[u][i] = min(dp[u][i], dp[v][j] + dp[u][i - j]);
            }
        }
    }
    if (w[u] <= m)
        dp[u][w[u]] = 1;
}
int main()
{
    cin >> n >> m;
    for (int i = 0, x; i < n; ++i)
    {
        string s;
        cin >> s >> x;
        s += "/";
        int len = s.size(), p = 0;
        string tmp = "";
        for (int j = 1; j < len; ++j)
        {
            tmp += s[j];
            if (s[j] == '/')
            {
                int now = id.count(tmp) ? id[tmp] : (id[tmp] = ++tot);
                G[p].emplace_back(now);
                p = now;
            }
        }
        w[p] = x;
    }
    dfs(0);
    if (dp[0][m] >= INF)
        dp[0][m] = -1;
    cout << dp[0][m] << endl;
    return 0;
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值