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';
}
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';
}
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';
}