【题解】Codeforces Round #700 (Div. 2)
作者:互联网
前言
蒟蒻的第一把\(Codeforces\),不出意料地成功考砸了。最大的感触就是这次\(CF\)的题目基本都是思维题,很少会出现本蒟蒻刷的水题和模板题。本次比赛的\(A\)题明显是签到题,\(B\)题和\(C\)题涉及的知识点都比较基础,考验的是选手的思维水平。\(D1\),\(D2\)和\(E\),蒟蒻目前的水平还不足以总结。
总体来说,这把打得还算中规中矩,是蒟蒻的真实实力。不像前段时间打的几场水赛,随便打打暴力就混过去了,对实力的提升一点帮助都没有。值得一提的是,\(2\)小时\(15\)分钟的比赛时长真的很可以,本蒟蒻甚至没有扫过一眼后三题的题面。看来,男人不仅要有爆发力和持久,还要追求速度。
\(T1\) \(Yet\) \(Another\) \(String\) \(Game\)
题目大意
目前有两个人正在玩游戏。每次可以从给定的由小写字母字符串\(s\)中挑选出一个没有被修改过的位置,将其修改成另外一个和原来不同小写字母。玩家\(A\)的目的是让最终的字符串\(s\)字典序尽量小,玩家\(B\)的目的是让最终的字符串\(s\)字典序尽量大。已知\(A\)是先手,\(B\)是后手,试求字符串\(s\)最终的样子。
输入数据由\(t\)组数据组成,\(t \leq 1000\),字符串的长度\(|s| \leq 50\)。
解题思路
显然,如果要对字典序产生最大的影响,我们一定会选择位置最靠前的位置进行修改。为了让字典序尽量小,\(A\)一定会把这个字母修改成\(a\),如果原来是\(a\)则修改成\(b\);为了让字典序尽量大,\(B\)一定会把这个字母修改成\(z\),如果原来是\(z\)则修改成\(y\)。
\(A\)和\(B\)轮流修改,并且两人一定会选择最靠前的位置。因此,假设第一个位置为\(0\),则偶数位置会被\(A\)修改,奇数位置会被\(B\)修改。按照最优的策略模拟即可。
参考代码
#include <iostream>
#include <string>
using namespace std;
int t;
string s;
int main()
{
cin >> t;
while (t--)
{
cin >> s;
for (int i = 0; i < s.length(); i++)
{
if (!(i % 2))
{
if (s[i] != 'a')
s[i] = 'a';
else
s[i] = 'b';
}
else
{
if (s[i] != 'z')
s[i] = 'z';
else
s[i] = 'y';
}
}
cout << s << endl;
}
return 0;
}
\(T2\) \(The\) \(Great\) \(Hero\)
题目大意
已知有一位英雄和\(n\)只怪物。英雄和怪物都有其对应的生命值和攻击力。英雄的初始生命值为\(B\),攻击力为\(A\)。第\(i\)头怪物的生命值为\(b_{i}\),攻击力为\(a_{i}\)。每一次,英雄都可以选择一只未死亡的怪物并与其战斗,战斗过后英雄和该怪物的生命值分别会变成\(B - a_{i}\)和\(b_{i} - A\)。如果生命值 \(\leq 0\),代表英雄或怪物已经死亡,否则代表存活。试求英雄能否杀死所有的怪物,注意,英雄和最后一头怪物同归于尽也算是杀死所有的怪物。如果能,输出YES
,否则输出NO
。
输入由\(t\)组数据组成,\(t \leq 10^5\),\(A, B \leq 10^6\),\(n \leq 10^5\),\(a_{i}, b_{i} \leq 10^6\)。
解题思路
显然,杀死一头怪物所要消耗的生命值是固定的。设\(cost_{i}\)为英雄杀死第\(i\)头怪物所需要的生命值,显然,\(cost_{i}\)等于杀死第\(i\)头怪物所需要的攻击次数乘上第\(i\)头怪物的攻击力,即\(cost_{i} = \lceil \frac{b_{i}}{A} \rceil \times a_{i}\)。注意,假如英雄攻击怪物后怪物已经死亡,英雄的生命值依然会减少。
设\(sum\)为\(\sum\limits_{i = 1}^n cost_{i}\)。\(c_{i}\)为杀死其他\(n - 1\)头怪物后,杀死最后的第\(i\)头怪物的前一回合英雄所剩的生命值。\(c_{i}\)等于杀死所有怪物所需要的生命值\(sum\),减去怪物发动的最后一次攻击给英雄造成的伤害\(a_{i}\)。如果\(c_{i} > 0\),说明英雄有能力给怪物最后一击,答案为YES
,否则,英雄在给怪物最后一击之前就已经去世,答案为NO
。
枚举最后一头杀死怪物,如果\(max(c_{i}) > 0\),说明英雄可以杀死所有的怪物,反之,英雄在杀死所有怪物前就已经去世。至此,这道题可以在\(O(nt)\)的时间复杂度内解决,无需贪心策略和排序操作。
参考代码
#include <cstdio>
using namespace std;
#define maxn 100005
int t, n;
long long A, B;
long long a[maxn], b[maxn], c[maxn], h[maxn];
long long get_ceil(long long a, long long b)
{
if (a % b)
return a / b + 1;
return a / b;
}
int main()
{
bool flag;
long long sum;
scanf("%d", &t);
while (t--)
{
sum = 0;
flag = false;
scanf("%lld%lld%d", &A, &B, &n);
for (int i = 1; i <= n; i++)
scanf("%lld", &a[i]);
for (int i = 1; i <= n; i++)
{
scanf("%lld", &b[i]);
c[i] = get_ceil(b[i], A);
sum += c[i] * a[i];
}
for (int i = 1; i <= n; i++)
{
h[i] = B - sum + a[i];
if (h[i] > 0)
{
flag = true;
break;
}
}
if (flag)
printf("YES\n");
else
printf("NO\n");
}
return 0;
}
\(T3\) \(Searching\) \(Local\) \(Minimum\)
题目大意
本题是交互式题目。
定义一个\(Local\) \(Minimum\)为\(1\)到\(n\)的全排列\(a\)中的某个位置\(i\),且\(i\)满足\(a_{i}\)小于其左右两侧的最小值,即\(a_{i} < min(a_{i - 1}, a_{i + 1})\)。\(a_{n}\)的右侧\(a_{n + 1} = a_{0} = \infty\)。现在,你可以像评测系统提出不超过\(100\)个问题,作为回答,评测系统会给出第\(i\)个位置上的元素\(a_{i}\)。询问结束后,你需要给出任意一个\(Local\) \(Minimum\)。
\(n \leq 10^5\),\(a_{i} \leq n\)。
解题思路
显然,对于这种查询某个元素的题目,我们需要用二分搜索来解决。显然,我们需要分析这个问题是否单调。
假设\(Local\) \(Minimum\)所在的区间为\(\left[ l, r \right]\),其中点为\(mid\)。现在给出重要前提:目前的中点可能不是答案。假如\(a_{mid} < a_{mid + 1}\),说明区间\(\left[ l, mid \right]\)一定是单调递增的,下面给出证明:
因为中点\(mid\)可能不是答案,且\(a_{mid} < a_{mid + 1}\),说明\(a_{mid} > a_{mid - 1}\),否则\(mid\)就是答案。同理,\(a_{mid - 1} > a_{mid - 2}, a_{mid - 2} > a_{mid - 3}\)……由此可知区间\(\left[ l, mid \right]\)一定是单调递增的。
同理,假如\(a_{mid} > a_{mid + 1}\),问题同样单调。由此可以确定,这道题的正解就是二分。假如\(a_{mid} < a_{mid + 1}\),在左区间内继续查找;反之在右区间内继续查找。
参考代码
#include <cstdio>
using namespace std;
#define maxn 100005
int n;
int a[maxn];
int main()
{
scanf("%d", &n);
int l = 1, r = n;
while (l < r)
{
int mid = (l + r) / 2;
if (!a[mid])
{
printf("? %d\n", mid);
fflush(stdout);
scanf("%d", &a[mid]);
}
if (!a[mid + 1])
{
printf("? %d\n", mid + 1);
fflush(stdout);
scanf("%d", &a[mid + 1]);
}
if (a[mid] < a[mid + 1])
r = mid;
else
l = mid + 1;
}
printf("! %d\n", l);
return 0;
}
标签:int,题解,700,mid,long,leq,怪物,Div,英雄 来源: https://www.cnblogs.com/Ling-Lover/p/700-div2.html