Codeforces Round #850(div1.div2)

Problem - A1 - Codeforces

Non-alternating Deck (easy version)

思路:

我们可以发现每次交换玩家发牌数增加 4 ,那么我们用一个变量 f 来标记当前应该给谁发牌。每次发 i 张牌就从牌堆减去 i 。最后剩下的 n 张牌再判断 f 发牌即可。

参考代码:

void solve() {
    int n, a{1}, b{}, f{1};
    std::cin >> n;
    n--;
    for (int i = 5; i <= n; i += 4)
    {
        if (n < i)
            break;
        if (f & 1)
            b += i;
        else
            a += i;
        n -= i, f++;
    }
    if (n)
    {
        if (f & 1)
            b += n;
        else
            a += n;
    }
    std::cout << a << ' ' << b << '\n';
}

Problem - A2 - Codeforces

Alternating Deck (hard version) 

思路:

每个人可以取到的牌都是奇数,那么每轮第一张牌取到什么颜色,最后一张牌也是这个颜色。

A 每轮取到的白色牌比黑色牌多 1 , B 反之。

最后同 easy version 模拟即可。

参考代码:

void solve()
{
    int n;
    std::cin >> n;
    n--;
    int a1{1}, a2{}, b1{}, b2{}, f{1}; // 1存白色 2存黑色
    for (int i = 5; i <= n; i += 4)
    {
        if (n < i)
            break;
        if (f & 1)
        {
            b2 += (i >> 1) + 1;
            b1 += (i >> 1);
        }
        else
        {
            a1 += (i >> 1) + 1;
            a2 += (i >> 1);
        }
        n -= i, f++;
    }
    if (n)
    {
        if (f & 1)
        {
            b2 += ceil(n / 2.0);
            b1 += (n >> 1);
        }
        else
        {
            a1 += ceil(n / 2.0);
            a2 += (n >> 1);
        }
    }
    std::cout << a1 << ' ' << a2 << ' ' << b1 << ' ' << b2 << '\n';
}

Problem - C - Codeforces

Monsters (easy version)

题意:

在电脑游戏中,你要对抗 n 个怪物。怪物 i 有 ai 生命值,所有 ai 都是整数。当怪物至少有 1 点生命值时,它是活着的。你可以使用两种类型的法术:

  • 对任何一个你选择的怪物造成 1 点伤害。
  • 对所有怪物造成 1 点伤害。

如果至少有一个怪物因为这个动作而死亡(生命值为 0 ),那么就重复这个动作(并且每次都至少有一个怪物死亡)。对怪物造成 1 点伤害会使其生命值降低 1 点。类型 1 的法术可以施放任意次数,而类型 2 的法术在游戏中最多只能施放一次。你最少需要使用多少次类型 1 法术才能杀死所有怪物?

思路:

类型 2 的法术可以将从生命值从 1 开始的严格非递减到 n 序列的怪物全部杀死,那么很明显我们可以通过类型 1 的法术将怪物血量变为严格非递减序列。在这个过程中使用的类型 1 法术次数即为结果。 

参考代码:

void solve() {
    int n;
    std::cin >> n;
    std::vector<int> v(n);
    for (int i = 0; i < n; i++)
        std::cin >> v[i];
    std::sort(v.begin(), v.end());
    ll cnt{}, d{1};
    for (int i = 0; i < n; i++)
    {
        if (i && v[i] == v[i - 1] && v[i] < d)
            continue;
        cnt += v[i] - d;
        d++;
    }
    std::cout << cnt << '\n';
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值