CF 简单杂题集
按照 2020,2021 年 CF 简单题精选 此题单
所有代码的开头头文件,宏定义和命名空间如下
#include <bits/stdc++.h> #define Tp template<typename Ty> #define Ts template<typename Ty,typename... Ar> #define ll long long #define CI const int #define RI int #define W while #define gc getchar #define max(x,y) ((x)>(y)?(x):(y)) #define min(x,y) ((x)<(y)?(x):(y)) #define Mt(a,x) memset((a),(x),sizeof(a)) using namespace std; namespace SlowIO { void Readc (char& c) {W (isspace (c = gc ()));} Tp void Read (Ty& x) {char c; int f = 1; x = 0; W (! isdigit (c = gc ())) f = c ^ '-' ? 1 : -1; W (x = (x * 10) + (c ^ 48), isdigit (c = gc ())); x *= f;} Ts void Read (Ty& x, Ar&... y) {Read (x); Read (y...);} } using namespace SlowIO;
CF1292B Aroma's Search
solution
发现 \(b_x,b_y\) 特别大,而 \(t \le 10^{16}\),所以即使 Aroma 一开始就往最远的点走,大概能走到第 100 个点,所以可以预先存下 Aroma 可以走到的点的坐标。
显然,由于步数为曼哈顿距离,所以依次经过 \((x_i,y_i),(x_{i+1},y_{i+1}),\cdots,(x_j,y_j)\) 的距离和等于直接从 \((x_i,y_i)\) 走到 \((x_j,y_j)\)。
经过证明,不难发现如果 Aroma 在 \((x_i,y_i)\),他走到 \((x_{i+1},y_{i+1})\) 的距离大于他经过一系列点到达 \((x_0,y_0)\) 的距离。
所以考虑贪心,首先枚举所有数据点,使 Aroma 先走到此数据点 \((x_a,y_a)\) 上,在经过一系列点到达 \((x_0,y_0)\)。如果还有时间,再走到 \((x_{a+1},y_{a+1}),(x_{a+2},y_{a+2}),\cdots\)
code
CI N = 100; ll x0, y0, ax, ay, bx, by, xs, ys, tt, X[N + 5], Y[N + 5], n;
ll dist (ll xx, ll yy, ll xxx, ll yyy) {return llabs (xx - xxx) + llabs (yy - yyy);}
int main () {
RI i, j; Read (x0, y0, ax, ay, bx, by, xs, ys, tt);
X[1] = x0, Y[1] = y0; n = 1; W (++ n) {
X[n] = ax * X[n - 1] + bx, Y[n] = ay * Y[n - 1] + by; if (X[n] > xs && Y[n] > ys && dist (xs, ys, X[n], Y[n]) > tt) break;
} ll ans = 0;
for (i = 1; i <= n; ++ i) {
ll now = 0, t = tt; t -= dist (xs, ys, X[i], Y[i]); if (t >= 0) ++ now; ll nowx = X[i], nowy = Y[i];
for (j = i - 1; j >= 1 && t >= 0; -- j) {
t -= dist (nowx, nowy, X[j], Y[j]); if (t >= 0) ++ now; nowx = X[j], nowy = Y[j];
} for (j = i + 1; j <= n && t >= 0; ++ j) {
t -= dist (nowx, nowy, X[j], Y[j]); if (t >= 0) ++ now; nowx = X[j], nowy = Y[j];
} ans = max (ans, now);
} printf ("%lld\n", ans);
return 0;
}