Codeforces Round 541 (Div. 2) 解题报告
对应场次为 CF1131
A. Sea Battle
align 排列,排整齐
adjacent 相邻
题目大意
给定两个矩形的长宽 \(w_1, h_1, w_2, h_2 (1 \le w_1, h_1, w_2, h_2 \le 10^8)\) 然后把两个矩形左边对齐摞在一起
问把这个东西包围一圈要多少个格子


Solution
首先考虑单个矩形围一圈 显然是 \(2 \times (w + h) + 4\)
然后考虑先把这俩分开然后合一起 看看哪些被撞没了

发现显然是 \(2 \times (\min(w_1, w_2) + 2)\)
然后就没了
点击查看代码
/*
*/
#include <bits/stdc++.h>
#define ll long long
using namespace std;
inline int read() {
int xr = 0, F = 1;
char cr;
while (cr = getchar(), cr < '0' || cr > '9') if (cr == '-') F = -1;
while (cr >= '0' && cr <= '9')
xr = (xr << 3) + (xr << 1) + (cr ^ 48), cr = getchar();
return xr * F;
}
void write(ll x) {
char ws[51];
int wt = 0;
if (x < 0) putchar('-'), x = -x;
do {
ws[++wt] = x % 10 + '0';
x /= 10;
} while (x);
for (int i = wt; i; --i) putchar(ws[i]);
}
namespace steven24 {
int w1, h1, w2, h2;
void main() {
w1 = read(), h1 = read(), w2 = read(), h2 = read();
int l1 = 2 * (w1 + h1) + 4;
int l2 = 2 * (w2 + h2) + 4;
int ans = l1 + l2;
ans -= (min(w1, w2) + 2) * 2;
write(ans), putchar('\n');
}
}
int main() {
steven24::main();
return 0;
}
B. Draw!
摆烂了不想啃生肉了
题目大意
给定 \(n(1 \le n \le 10^4)\) 个足球赛过程中的比分
询问最多可能会有多少平局
Solution
考虑两次比赛之间两队比分的取值范围 显然为 \(\left[a_{i - 1}, a_i\right]\) 和 \(\left[b_{i - 1}, b_i\right]\)
那么平局就是这两个区间的交
但是通过样例2 我们发现有些比分会被重复计算
所以记一个 \(lst\) 表示上一次计算的比分的右端点 如果这次的左端点与 \(lst\) 相等就给答案-1
点击查看代码
/*
*/
#include <bits/stdc++.h>
#define ll long long
using namespace std;
inline int read() {
int xr = 0, F = 1;
char cr;
while (cr = getchar(), cr < '0' || cr > '9') if (cr == '-') F = -1;
while (cr >= '0' && cr <= '9')
xr = (xr << 3) + (xr << 1) + (cr ^ 48), cr = getchar();
return xr * F;
}
void write(ll x) {
char ws[51];
int wt = 0;
if (x < 0) putchar('-'), x = -x;
do {
ws[++wt] = x % 10 + '0';
x /= 10;
} while (x);
for (int i = wt; i; --i) putchar(ws[i]);
}
namespace steven24 {
const int N = 1e4 + 0721;
int a[N], b[N];
int n, ans;
void main() {
n = read();
for (int i = 1; i <= n; ++i) a[i] = read(), b[i] = read();
ans = 1;
int lst = 0;
for (int i = 1; i <= n; ++i) {
if (min(a[i], b[i]) - max(a[i - 1], b[i - 1]) + 1 <= 0) continue;
ans += min(a[i], b[i]) - max(a[i - 1], b[i - 1]) + 1;
if (lst == max(a[i - 1], b[i - 1])) --ans;
lst = min(a[i], b[i]);
}
write(ans), putchar('\n');
}
}
int main() {
steven24::main();
return 0;
}
C. Birthday
题目大意
给你 \(n(1 \le n \le 10^2)\) 个数 你可以把它们按任意顺序排成一个环 使得相邻两个元素之差的绝对值最大值最小 输出方案
Solution
起手排序肯定是没啥问题的
然后根据直觉应该是类似于 \(a_1, a_3, a_5, ..., a_6, a_4, a_2\) 这样的山峰形最优
所以直接按这个输出即可
点击查看代码
/*
*/
#include <bits/stdc++.h>
#define ll long long
using namespace std;
inline int read() {
int xr = 0, F = 1;
char cr;
while (cr = getchar(), cr < '0' || cr > '9') if (cr == '-') F = -1;
while (cr >= '0' && cr <= '9')
xr = (xr << 3) + (xr << 1) + (cr ^ 48), cr = getchar();
return xr * F;
}
void write(ll x) {
char ws[51];
int wt = 0;
if (x < 0) putchar('-'), x = -x;
do {
ws[++wt] = x % 10 + '0';
x /= 10;
} while (x);
for (int i = wt; i; --i) putchar(ws[i]);
}
namespace steven24 {
const int N = 521;
int a[N];
int n;
void main() {
n = read();
for (int i = 1; i <= n; ++i) a[i] = read();
sort(a + 1, a + 1 + n);
for (int i = 1; i <= n; ++i) if (i & 1) write(a[i]), putchar(' ');
for (int i = n; i; --i) if (!(i & 1)) write(a[i]), putchar(' ');
}
}
int main() {
steven24::main();
return 0;
}
D. Gourmet choice
题目大意
给定两个序列的长度 \(n, m(1 \le n, m \le 1000)\) 再给出一个 \(n \times m\) 的矩阵 \(i\) 行 \(j\) 列表示 \(a_i\) 与 \(b_j\) 的大小关系 输出一个构造方案
Solution
做法一:
直接差分约束跑 spfa 稠密图因为 vector 是连续调用比链前快 可以直接艹过去
做法二:
用并查集维护所有相等的变量 然后用有向边维护大小关系
拓扑排序即可

浙公网安备 33010602011771号