B. Charmed by the Game
题目大意:
A和B轮流发球,给出A和B的胜利场数a和b,但是不知道谁先发球,问最后破发球次数的所有可能。接球一方胜利即为破发球。
题解:
因为不知道谁先发球,所以可以分为两种情况, 一种为A先发球,另一种为B先发球
每个人发球的次数很容易得出来,定义x = (a + b) / 2,y = a + b - x 那么A要么发球x次,要么发球y次。
A发球x次:若A在发球中胜利i次,那么A就有a - i次破发球,B就有x - i破发球,a - i + x - i即为总破发球次数。
当然这里要注意 a - i <= y && i <= x;因为破发球是在接球过程,A发球x次,B就接球y次,发球胜利的场次必定不大于发球次数
A发球B次同理
代码如下:
void solve()
{
int a, b; scanf("%d%d", &a, &b);
int x = (a + b) / 2;
int y = a + b - x;
//set存储,自动排序加去重
set<int> s;
//A发球x次
for (int i = 0; i <= a; i ++ )
{
if (a - i <= y && i <= x)
s.insert(x - i + a - i);
}
//A发球y次,可以看作B发球x次
for (int i = 0; i <= b; i ++ )
{
if (b - i <= y && i <= x)
s.insert(x - i + b - i);
}
printf("%d\n", s.size());
for (auto i : s)
printf("%d ", i);
printf("\n");
}
C. Deep Down Below
题意:
一个英雄进入n个洞穴,第i个洞穴有ki个怪兽,每个怪兽都有一定的护甲值,当且仅当英雄的攻击力严格大于怪兽的护甲时才能击败怪兽。英雄进入洞穴后按照顺序击败怪兽,每击败一个怪兽攻击力+1,问英雄击败所有洞穴的怪兽所需的最小攻击力
题解:
当英雄进入洞穴时攻击力为x,该洞穴内第i个怪兽护甲值为ai(0 < i < k)那么对于第i个怪兽要满足x + i > ai才可以,那么进入洞穴前的攻击力就要满足x > ai - i
所以对于进入每一个洞穴我们都要找到一个满足x > ai - i的初始最小攻击力即max(ai - i)
我们肯定要先从初始攻击力最小的洞穴进,这样才能保证进入后续洞穴时初始攻击力尽可能的大且英雄所需攻击力最小,所以对进入所有洞穴的初始最小攻击力进行排序即可
代码如下:
//pair数组,first为英雄攻击力,second为每个洞穴可以增加的攻击力
PII a[N];
int n;
void solve()
{
scanf("%d", &n);
for (int i = 0; i < n; i ++ )
{
int m; scanf("%d", &m);
int mx = 0;
for (int j = 0; j < m; j ++ )
{
int x; scanf("%d", &x);
mx = max(mx, x - j);
}
a[i] = {mx, m};
}
sort(a, a + n);
int ans = 0, pow = 0;
//ans为初始英雄最小攻击力,pow为增加的攻击力
for (int i = 0; i < n; i ++ )
{
if (ans + pow < a[i].first) ans = a[i].first - pow;
pow += a[i].second;
}
//这里要+1,因为要严格大于
printf("%d\n", ans + 1);
}