Atcoder Beginner Contest 422
A
按照题意输出即可。
/*********************************************************************
程序名:
作者: xAlec
日期: 2025-10-01 15:45
说明: sakana ~
*********************************************************************/
#include <bits/stdc++.h>
#define int long long
using namespace std;
int x, y;
char ch;
signed main() {
cin >> x >> ch >> y;
if (y < 8)
cout << x << ch << y + 1 << '\n';
else if (x < 8 && y == 8)
cout << x + 1 << ch << 1 << '\n';
}
B
按照题意模拟即可。
/*********************************************************************
程序名:
作者: xAlec
日期: 2025-10-01 15:45
说明: sakana ~
*********************************************************************/
#include <bits/stdc++.h>
#define int long long
using namespace std;
int h, w;
char s[25][25];
signed main() {
scanf ("%lld %lld", &h, &w);
for (int i = 1; i <= h; i++)
scanf ("%s", s[i] + 1);
bool flag = true;
for (int i = 1; i <= h; i++) {
for (int j = 1; j <= w; j++) {
if (s[i][j] == '#') {
int cnt = 0;
cnt += (s[i - 1][j] == '#');
cnt += (s[i][j - 1] == '#');
cnt += (s[i + 1][j] == '#');
cnt += (s[i][j + 1] == '#');
if (cnt != 2 && cnt != 4) {
flag = false;
break;
}
}
}
if (!flag)
break;
}
if (flag)
puts("Yes");
else
puts("No");
return 0;
}
C
看完题第一反应是 \(\min(cnt_A,cnt_C)\),然后它 WA 了。
严肃思考后发现 \(cnt_B = 0\) 的时候需要特殊考虑,一般化就是因为三个位置要均分,最大的个数只能是 \(\lfloor\frac{n_A + n_B + n_C}{3}\rfloor\)。
#include <bits/stdc++.h>
#define int long long
using namespace std;
int test;
int na, nb, nc;
void sol() {
scanf ("%lld %lld %lld", &na, &nb, &nc);
int up = max(na, nc), down = min(na, nc);
printf ("%lld\n", min(down, (na + nb + nc) / 3));
}
signed main() {
scanf ("%lld", &test);
while (test--)
sol();
return 0;
}
D
读完题意可以发现,其实操作是线段树建树。由于总和均分,答案只有可能是 0/1。
#include <bits/stdc++.h>
#define int long long
using namespace std;
constexpr int MAXN = (1 << 20) + 3;
int n, K, a[MAXN], U;
inline int qpow(int x, int exp) {
int res = 1;
for (; exp; exp /= 2) {
if (exp & 1)
res = res * x;
x = x * x;
}
return res;
}
void build(int l, int r, int sum) {
if (l == r) {
a[l] = sum;
return;
}
int mid = (l + r) / 2;
build(l, mid, sum / 2);
build(mid + 1, r, sum - sum / 2);
}
signed main() {
scanf ("%lld %lld", &n, &K);
n = qpow(2, n);
build(1, n, K);
for (int i = 1; i < n; i ++) {
if (a[i] != a[i + 1]) {
U = 1;
break;
}
}
printf ("%lld\n", U);
for (int i = 1; i <= n; i++)
printf ("%lld%c", a[i], " \n"[i == n]);
return 0;
}
E
考虑两点 \((x_1, y_1), (x_2,y_2)\) 确定一条直线则有 \(ax_1 + by_1 + c = ax_2 + by_2 + c\),解得 \(\begin{cases}a = y_2 - y_1 \\ b = x_1 - x_2 \\ c = x_2y_1 - x_1y_2\end{cases}\)。
考虑一波随机化,每次随机两个点确定一条直线来判,好像概率挺高的,高达 \(25\%\)。
#include <bits/stdc++.h>
#define int long long
using namespace std;
random_device seed;
mt19937 rd(seed());
constexpr int MAXN = 5e5 + 10;
int n, a = -1, b = -1, c = -1;
pair<int,int> p[MAXN];
signed main() {
scanf ("%lld", &n);
for (int i = 1; i <= n; i++)
scanf ("%lld %lld", &p[i].first, &p[i].second);
for (int _ = 1; _ <= 100; _++) {
int x = rd() % n + 1, y = rd() % n + 1;
// cout << x << ' ' << y << '\n';
if (x != y) {
int ta = p[y].second - p[x].second,
tb = p[x].first - p[y].first,
tc = p[y].first * p[x].second - p[x].first * p[y].second,
tot = 0;
for (int i = 1; i <= n; i++)
tot += (ta * p[i].first + tb * p[i].second + tc == 0);
if (tot >= n / 2 + 1) {
a = ta, b = tb, c = tc;
break;
}
}
}
if (a == -1 && b == -1 && c == -1)
printf ("No\n");
else
printf ("Yes\n %lld %lld %lld\n", a, b, c);
return 0;
}
F
对于 \(u\) 节点的 \(W_u\),如果此时从它开始还有 \(x\) 步走到目的地,则它会被计算 \(x\) 次。
考虑记 \(f_{u,x}\) 表示当前在 \(u\) 节点,还有 \(x\) 步走到目的地的燃料最小花费。有转移:\(f_{v,x - 1} = \max\{f_{u,x} + w_u \times x\}\)。
答案即为每个 \(f_{i,0}\)。
#include <bits/stdc++.h>
#define FASTIO
#define int long long
using namespace std;
#ifdef FASTIO
static int ostk[33];
char buf[1 << 23], *p1, *p2;
#define getchar() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 23, stdin), p1 == p2) ? EOF : *p1++)
inline int read() {
int res = 0, f = 1;
char ch = getchar();
while (!isdigit(ch))
f = ch == '-' ? -1 : 1, ch = getchar();
while (isdigit(ch))
res = res * 10 + (ch ^ 48), ch = getchar();
return res * f;
}
inline void write(int x) {
int top = 0;
if (x < 0)
x = -x, putchar('-');
do {
ostk[top++] = x % 10;
x /= 10;
} while(x);
while(top)
putchar(ostk[--top] + '0');
}
#endif
constexpr int MAXN = 5005;
int n, m, idx;
int head[MAXN], w[MAXN];
int f[MAXN][MAXN];
struct graph {
int v, nxt;
} e[MAXN << 1];
inline void addedge(int u, int v) {
e[idx].v = v;
e[idx].nxt = head[u];
head[u] = idx++;
}
signed main() {
n = read();
m = read();
memset(head, -1, sizeof(head));
for (int i = 1; i <= n; i++)
w[i] = read();
for (int i = 1; i <= m; i++) {
int u = read(), v = read();
addedge(u, v), addedge(v, u);
}
memset(f, 0x3f, sizeof(f));
for (int u = 0; u <= n; u++)
f[1][u] = 0;
for (int j = n; j >= 1; j--) {
for (int u = 1; u <= n; u++) {
for (int i = head[u]; ~i; i = e[i].nxt) {
int v = e[i].v;
f[v][j - 1] = min(f[v][j - 1], f[u][j] + w[u] * j);
}
}
}
for (int i = 1; i <= n; i++)
write(f[i][0]), putchar('\n');
return 0;
}

浙公网安备 33010602011771号