牛客周赛Round 19

第一题:简单题,按题意模拟即可。

第二题:小红杀怪

小红在一个游戏里杀怪。这是个回合制游戏,小红和两只怪物相遇了。
第一只怪物有 aaa 血量,第二只怪物有 bbb 血量。
小红有两个技能:
第一个技能叫火球术,效果是对单体怪物造成 xxx 伤害。
第二个技能叫烈焰风暴,效果是对每只怪物造成 yyy 伤害。
小红想知道,自己最少使用多少次技能,可以击杀这两只怪物?(当怪物血量小于等于0时,视为被击杀)

数据范围:

1≤a,b,x,y≤20

输入:

5 2 3 1

输出:

3

代码:

#include <bits/stdc++.h>
using namespace std;
#pragma G++ optimize(2)
#define double long double
#define int long long
#define xiaowen ac
typedef unsigned long long ull;
typedef long long ll;
const double eps = 1e-8;
const int N = 2e6 + 7;
const int P = 131;

int a, b, x, y;
int res = 1e9;                   // 求最小值,初始为较大值
void Dfs(int a, int b, int step) // a:目前的血量 b:b怪目前的血量 step:当前的操作数
{

    if (a <= 0 && b <= 0)
    {
        res = min(res, step);
        return;
    }
    if (a + b <= -20) // 玄之一手,防止死循环
    {
        return;
    }
    Dfs(a - x, b, step + 1);
    Dfs(a, b - x, step + 1);
    Dfs(a - y, b - y, step + 1);
}
void solve()
{
    cin >> a >> b >> x >> y;
    if (x <= y) // 贪心一下,当x<=y时,选y总是比选x较优
    {
        int t = max(a, b);
        cout << (t + y - 1) / y; // 向上取整
    }
    else
    {                 // x>y
        Dfs(a, b, 0); // 数据范围较小,所以可以深搜
        cout << res << '\n';
    }
}

signed main()
{
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    std::cout.tie(nullptr);

    int T;
    // cin >> T;
    T = 1;
    while (T--)
    {
        solve();
    }
    return 0;
}

第三题:

利用dp进行预处理,最后统计答案。


小红的元素分裂
小红拿到了一个数组,她每次可以进行如下操作之一:
·选择一个元素xxx,将其分裂为111和x−1x-1x−1。
·选择一个元素xxx,将其分裂为aaa和bbb,需要保证a∗b=xa*b=xa∗b=x

小红希望用最少的操作次数,将所有数组的所有元素全部变成1。你能帮帮她吗?

数据范围:

1≤n,ai​≤105

输入:

2
2 6

输出:

5

代码:

#include <bits/stdc++.h>
using namespace std;
#pragma G++ optimize(2)
#define double long double
#define int long long
#define xiaowen ac
typedef unsigned long long ull;
typedef long long ll;
const double eps = 1e-8;
const int N = 1e5 + 7;
const int P = 131;

int dp[N]; // dp[i]表示当值为i时的最小操作数
void solve()
{
    int n;
    cin >> n;
    for (int i = 2; i <= N; i++)
    {
        int s = dp[i - 1] + 1; // 选第一种操作时的操作数

        // 求i去掉1和i后的因子
        for (int j = 2; j * j <= i; j++)
        {
            if (i % j == 0)
            {
                s = min(s, dp[j] + dp[i / j] + 1); // 选第二种操作数时的操作数,取最小
            }
        }
        dp[i] = s;
    }
    int res = 0;
    // 计算答案
    for (int i = 1; i <= n; i++)
    {
        int x;
        cin >> x;
        res += dp[x];
    }
    cout << res << '\n';
}

signed main()
{
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    std::cout.tie(nullptr);

    int T;
    // cin >> T;
    T = 1;
    while (T--)
    {
        solve();
    }
    return 0;
}

第四题:暂时不会.

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值