339
A - TLD
输出最后一个点后面的字符
void solve()
{
string a;
cin >> a;
for (int i = a.size() - 1; i >= 0; i--)
{
if (a[i] == '.')
{
for (int j = i + 1; j < a.size(); j++)
cout << a[j];
break;
}
}
}
B - Langton's Takahashi
给出要旋转的次数,刚开始方向向上且在
- 如果当前单元格是
.
,则将其变为#
,顺时针旋转,并沿着他面对的方向向前移动一个单元格。 - 否则,将当前单元格变为
.
,逆时针旋转,并沿着他所面对的方向向前移动一个单元格。
输出最后的二维字符串.
Solution
坑点:刚开始是向上的,所以 curDir = 3;
而不是
主要是顺时针与逆时针旋转:
int directions[4][2] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
curDir = (curDir + 1) % 4; // 顺时针
curDir = (curDir + 3) % 4; // 逆时针
void solve()
{
int H, W, N;
cin >> H >> W >> N;
vector<vector<char>> grid(H, vector<char>(W, '.')); // Initialize the grid with all white cells
int x = 0, y = 0; //位置
int directions[4][2] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
int curDir = 3;
for (int i = 0; i < N; i++)
{
if (grid[x][y] == '.')
{
grid[x][y] = '#';
curDir = (curDir + 1) % 4; // 顺时针
}
else
{
grid[x][y] = '.'; // Change color
curDir = (curDir + 3) % 4; // 逆时针
}
x += directions[curDir][0];
y += directions[curDir][1]; // Move to the next cell
x = (x + H) % H; // Wrap around if out of bounds
y = (y + W) % W; // Wrap around if out of bounds
}
// Print the grid
for (int i = 0; i < H; i++)
{
for (int j = 0; j < W; j++)
cout << grid[i][j];
cout << endl;
}
}
C - Perfect Bus
一辆公共汽车正在运营。公共汽车上的乘客人数总是一个非负整数。
在某一时刻,公交车上的乘客人数为零或更多,此后公交车停靠了
请找出与给定信息相符的当前公交车上乘客人数的最小值。
Solution
很简单,算出刚开始的乘客有多少即可。
利用前缀和算出乘客最有可能为 0 的位置,在那个位置刚好为 0 即可,再加上从开始到最后折合上来的人数即可。
#define int long long
void solve()
{
int n;
cin >> n;
vector<int> a(n + 1), pre(n + 1);
for (int i = 1; i <= n; i++)
cin >> a[i];
pre[1] = a[1];
for (int i = 2; i <= n; i++)
pre[i] = pre[i - 1] + a[i];
int ini = 0;
for (int i = 1; i <= n; i++)
ini = min(ini, pre[i]);
cout << abs(ini) + pre[n] << ' ';
}
D - Synchronized Players
有一个
网格中不同的空单元上也有两个玩家。每个单元格的信息以长度为
-
如果
的 个字符是 P
,上面有一名棋手。 -
如果
的 个字符是 .
,是空格。 -
如果
的 个字符是 #
,包含一个障碍物。
重复下面的操作,找出将两位棋手带到同一格所需的最少步数。如果重复操作无法将两位棋手带到同一格,则打印 -1
。
- 从四个方向中选择一个:上、下、左或右。然后,每个玩家都会尝试移动到该方向的相邻单元格。如果目标单元格存在且为空,则每个玩家都会移动,否则不会移动。
Solution
搜索(bfs)
官方题解:
现在我们的图是一个有
每次操作后在顶点
假设初始时两个玩家的位置分别是
(待更
E - Smooth Subsequence
给出
Solution
线段树
官方题解:
在这种情况下,
此公式用于计算 dp 数组,可以得到正确的答案,但时间复杂度和空间复杂度为
因此,我们可以使用
通过不显式地存储每个
这样,空间复杂度就变成了
void solve()
{
int n, d;
cin >> n >> d;
vector<int> a(n);
for (int i = 0; i < n; i++)
cin >> a[i];
vector<int> dp(n, 0);
for (int i = 0; i < n; i++)
{
dp[i] = 1;
for (int j = 0; j < i; j++)
if (abs(a[i] - a[j]) <= d)//a[i]和a[i]前面的数比较是否<=d,如果有,直接等于那个数的最大长度+1
dp[i] = max(dp[i], dp[j] + 1);
}
int ans = *max_element(dp.begin(), dp.end());
cout << ans << '\n';
}
#include <bits/stdc++.h>
using namespace std;
const int A = 500010;
int seg[A * 4];
void update(int v, int tl, int tr, int pos, int new_val)
{
if (tl == tr)
seg[v] = new_val;
else
{
int tm = (tl + tr) / 2;
if (pos <= tm)
update(v * 2, tl, tm, pos, new_val);
else
update(v * 2 + 1, tm + 1, tr, pos, new_val);
seg[v] = max(seg[v * 2], seg[v * 2 + 1]);
}
}
int query(int v, int tl, int tr, int l, int r)
{
if (l > r)
return 0;
if (l == tl && r == tr)
return seg[v];
int tm = (tl + tr) / 2;
return max(query(v * 2, tl, tm, l, min(r, tm)),
query(v * 2 + 1, tm + 1, tr, max(l, tm + 1), r));
}
int main()
{
int n, d;
cin >> n >> d;
vector<int> a(n);
for (int &e : a)
cin >> e;
for (int i = 0; i < n; i++)
{
int l = max(0, a[i] - d);
int r = min(A - 1, a[i] + d);
int mx = query(1, 0, A - 1, l, r);
update(1, 0, A - 1, a[i], mx + 1);
}
cout << seg[1] << '\n';
}
F - Product Equality
给你
求满足以下条件的整数
( )
Solution
官方题解:(看不懂)
有
首先,让我们考虑判断三个变量
- 选择一个整数
,如果 (mod x),那么我们判定 。
这种方法会在
接下来,我们可以考虑选择素数
因此,实际上以下的随机算法是正确的解决方法:
- 令
为随机选择的素数集合(每个值都是 以上 以下的素数)。 - 对于
中的每个元素 ,如果对所有的 , (mod x)成立,则判定 。 - 首先对所有的
,对 中的每个元素 进行取模运算,然后判断 的取模值是否与之匹配。
通过这种方法,我们可以在
此外,我们也可以只选择足够大的整数,而不进行素数判断,同样也可以得到这个问题的正确解。(很难准备这样的案例,使得这种解法失败)
(待更
G - Smaller Sum
给你一个长度为
请回答以下
- 求
中不大于 的元素之和。
在此,您需要在线回答这些查询。
也就是说,只有在回答了当前查询后,下一个查询才会显示出来。
因此,我们给你的不是
- 让
和 ( -th 查询的答案)。 - 然后,查询可以按如下方式解密:
Solution
(待更