A - TLD
AtCoder: A - TLD
洛谷: [ABC339A] TLD
思路
从后往前枚举,找到最后一个 所在的位置,输出它后面的所有字符(不包含 )。
代码
#include<iostream>
using namespace std;
int main() {string s;cin >> s;int k = s.size() - 1;while (k >= 0 && s[k] != '.') k--;for (int i = k + 1; i < s.size(); i++) cout << s[i];cout << endl;return 0;
}
B - Langton's Takahashi
AtCoder: B - Langton's Takahashi
洛谷: [ABC339B] Langton's Takahashi
思路
直接按照题目模拟即可。
代码
#include<iostream>
#include<cstring>
using namespace std;
const int N = 103;
char grid[N][N];
int off[4][2] = { -1, 0, 0, 1, 1, 0, 0, -1 }; // 方向数组
int h, w, n;// 0为上,1为右,2为下,3为左// 执行一次题目中的操作
void doit(int& x, int& y, int& dir) {if (grid[x][y] == '.') {grid[x][y] = '#';// 顺时针旋转90度if (dir == 3) dir = 0;else dir++;}else {grid[x][y] = '.';// 逆时针旋转90度if (dir == 0) dir = 3;else dir--;}x += off[dir][0];y += off[dir][1];if (x == 0) x = h;else if (x == h + 1) x = 1;if (y == 0) y = w;else if (y == w + 1) y = 1;
}int main() {cin >> h >> w >> n;memset(grid, '.', sizeof grid); // 开始时全部为白色int x = 1, y = 1, dir = 0;while (n--) doit(x, y, dir); // 执行n次操作// 输出for (int i = 1; i <= h; i++) {for (int j = 1; j <= w; j++) cout << grid[i][j];cout << endl;}return 0;
}
C - Perfect Bus
思路
难点在于计算初始人数。
先不管条件,设初始时车上没有人,再模拟一遍上下车,找出这期间车上人数的最小值。
如果为负数,则初始时车上的人数为最小值的相反数。
算出初始人数后,计算最终结果。
代码
#include<iostream>
using namespace std;
typedef long long ll;
int main() {ll n, x;cin >> n;ll cur = 0, minn = 0;while (n--) {cin >> x;cur += x;minn = min(minn, cur);}cout << max(0ll, -minn) + cur << endl;return 0;
}
D - Synchronized Players
思路
数据范围不大,暴力bfs就行。
设数组vis,表示状态是否访问过。
从两个玩家起始的位置开始搜索,首先把起始状态丢入队列。
对于每个状态,尝试让两个
玩家移动到上下左右四个位置,如果有一个玩家移动后出界或者是移动到障碍物上,那就不动它。
在看一个新的状态时,如果没有访问过,那就扔进队列。
当两个玩家位置重合,就输出步数。
如果队列为空时仍未找到答案,输出-1。
代码
#include<iostream>
#include<queue>
using namespace std;
const int N = 70;
int n;
char map[N][N];
bool vis[N][N][N][N];
const int dir[4][2] = { -1,0,0,1,1,0,0,-1 };// 表示状态的结构体
struct node {int x1, y1, x2, y2, step;
};
queue<node> q;// 把一个状态扔进队列并标记
void que_add(int x1, int y1, int x2, int y2, int s) {node p = { x1,y1,x2,y2,s };vis[x1][y1][x2][y2] = true;q.push(p);
}// 检查点(x,y)是否合法
bool check(int x, int y) {if (x<1 || x>n || y<1 || y>n) return false;if (map[x][y] == '#') return false;return true;
}// 广搜函数
int bfs(int x1, int y1, int x2, int y2) {que_add(x1, y1, x2, y2, 0); // 初始状态入队while (q.size()) {node t = q.front();q.pop();// 扩展节点for (int i = 0; i < 4; i++) {int nx1 = t.x1 + dir[i][0], ny1 = t.y1 + dir[i][1];int nx2 = t.x2 + dir[i][0], ny2 = t.y2 + dir[i][1];if (!check(nx1, ny1)) nx1 = t.x1, ny1 = t.y1;if (!check(nx2, ny2)) nx2 = t.x2, ny2 = t.y2;// 位置重合if (nx1 == nx2 && ny1 == ny2) return t.step + 1;// 如果没有访问过就扔进队列继续搜索if (!vis[nx1][ny1][nx2][ny2]) que_add(nx1, ny1, nx2, ny2, t.step + 1);}}return -1;
}int main() {int a = 0, b, c, d;ios::sync_with_stdio(0);cin.tie(0), cout.tie(0);cin >> n;for (int i = 1; i <= n; i++) {for (int j = 1; j <= n; j++) {cin >> map[i][j];if (map[i][j] == 'P') {if (a) c = i, d = j;else a = i, b = j;}}}cout << bfs(a, b, c, d) << endl;return 0;
}
E - Smooth Subsequence
思路
和最长不下降子序列相似,但是朴素的算法过不了,需要线段树优化。
这里,我们将范围内的数字作为节点,记录每个节点的dp值。
计算时查询范围内的最大值,取最大值+1作为(注意最小是1)。
再将线段树内数字对应点改为。
最后求线段树内所有点的最大值。
另外,输入的每个都要加上,保证为正整数,方便线段树处理。
代码
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>#define ls u << 1
#define rs u << 1 | 1using namespace std;
const int N = 1e6 + 10, INF = 0x3f3f3f3f;
int a[N], dp[N];
int n, d;struct Tree
{int l, r, mx;
}tr[N << 2];void pushup(int u)
{tr[u].mx = max(tr[ls].mx, tr[rs].mx);
}void build(int u, int l, int r)
{if (l == r){tr[u] = { l,l,-INF };return;}tr[u] = { l,r,-INF };int mid = l + r >> 1;build(ls, l, mid); build(rs, mid + 1, r);pushup(u);
}void modify(int u, int x, int val)
{if (tr[u].l == tr[u].r && tr[u].l == x){tr[u].mx = val;return;}int mid = tr[u].l + tr[u].r >> 1;if (x <= mid) modify(ls, x, val);else modify(rs, x, val);pushup(u);
}int query_mx(int u, int x, int y)
{if (x <= tr[u].l && y >= tr[u].r) return tr[u].mx;int mid = tr[u].l + tr[u].r >> 1;int res = -INF;if (x <= mid) res = query_mx(ls, x, y);if (y > mid) res = max(res, query_mx(rs, x, y));return res;
}int main()
{ios::sync_with_stdio(0);cin.tie(0), cout.tie(0);cin >> n >> d;for (int i = 1; i <= n; i++) {cin >> a[i];a[i] += 500000;}build(1, 1, N);for (int i = 1; i <= n; i++){dp[i] = max(1, query_mx(1, a[i] - d, a[i] + d) + 1);modify(1, a[i], dp[i]);}cout << query_mx(1, 1, N) << endl;return 0;
}