Codeforces Round 920 (Div. 3)

A. Square

思路:

  • 要计算矩形面积,直接统计上下左右的最值即可

时间复杂度:\(O(1)\)

1
2
3
4
5
6
7
8
9
10
11
12
13
void solve() {
int l = 1e4, d = 1e4, u = -1e4, r = -1e4;
for (int i = 0; i < 4; i++) {
int x, y;
std::cin >> x >> y;

l = std::min(l, x);
r = std::max(r, x);
u = std::max(u, y);
d = std::min(d, y);
}
std::cout << abs(l - r) * abs(u - d) << "\n";
}

B. Arranging Cats

思路:

  • 首先发现,只要1的个数在sf中发生了变化,答案的起始个数一定是这个差值
  • 在不变的数量里统计位置差异的个数,代码写的有点臃肿qwq

时间复杂度:\(O(n)\)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
void solve() {
int n;
std::cin >> n;

std::string s, f;
std::cin >> s >> f;

if (s == f) {
std::cout << "0\n";
return ;
}

int a = 0, b = 0, c = 0;
for (int i = 0; i < n; i++) {
if (s[i] == '1' && f[i] == '0') {
a++;
} else if (s[i] == '0' && f[i] == '1') {
b++;
}
}

if (b == n || a == n) {
std::cout << n << "\n";
return ;
}

int zs = std::count(s.begin(), s.end(), '0');
int os = std::count(s.begin(), s.end(), '1');
int zf = std::count(f.begin(), f.end(), '0');
int of = std::count(f.begin(), f.end(), '1');

int ans = abs(of - os);
b -= ans;
a -= ans;
std::cout << ans + std::max(b, a) << "\n";
}

C. Sending Messages

思路:

  • 直接在每一个区间中与关机的消耗取min,然后总的能量减去这个值,判断这个过程中是否会小于等于0即可

时间复杂度:\(O(nlogn)\)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
void solve() {
int n, f, a, b;
std::cin >> n >> f >> a >> b;

std::vector<int> m(n);
for (int i = 0; i < n; i++) {
std::cin >> m[i];
}

std::sort(m.begin(), m.end());

int lst = 0;
for (int i = 0; i < n; i++) {
f -= std::min(1ll * (m[i] - lst) * a, 1ll * b);
lst = m[i];
if (f <= 0) {
std::cout << "NO\n";
return ;
}
}
std::cout << "YES\n";
}

D. Very Different Array

思路:

  • 结论:存在两个序列a, b,如果其中一个升序,另外一个降序,那么这一个序列的差值和一定最大
  • 用这个结论模拟即可,注意爆int

时间复杂度:\(O(nlogn)\)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
void solve() {
int n, m;
std::cin >> n >> m;

std::vector<int> a(n), b(m);
for (int i = 0; i < n; i++) {
std::cin >> a[i];
}
for (int i = 0; i < m; i++) {
std::cin >> b[i];
}

std::sort(a.begin(), a.end());
std::sort(b.begin(), b.end(), std::greater());

int p = 0;
std::vector<int> v;
while (true) {
if (v.size() == n) {
std::cout << std::accumulate(v.begin(), v.end(), 0ll) << "\n";
return ;
}
int x = abs(b.back() - a.back());
int y = abs(b[p]- a[p]);

if (x > y) {
v.push_back(x);
b.pop_back();
a.pop_back();
} else {
v.push_back(y);
p++;
}
}
}

E. Eat the Chip

思路:

  • 首先可以发现,如果这种情况,一定平局,黑色选中区域为它们占据的单元格
情况1
  • 还有两种是别距离为奇数和距离为偶数的情况
    • 如果是奇数,那么如果Alice可以在有限的时间里把Bob逼到墙边就获胜,否则平局
    • 如果是偶数,那么如果Bob可以在有限的时间里把Alice逼到墙边就获胜,否则平局
情况2

时间复杂度:\(O(1)\)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
void solve() {
int h, w, xa, ya, xb, yb;
std::cin >> h >> w >> xa >> ya >> xb >> yb;

if (xa >= xb) {
std::cout << "Draw\n";
} else if ((xb - xa) % 2 == 1) {
int t = (xb - xa + 1) / 2; // 相遇时间
if (abs(ya - yb) <= 1 || yb < ya && ya - 1 <= t || yb > ya && w - ya <= t) {
std::cout << "Alice\n";
} else {
std::cout << "Draw\n";
}
} else {
int t = (xb - xa) / 2;
if (ya == yb || ya < yb && yb - 1 <= t || ya > yb && w - yb <= t) {
std::cout << "Bob\n";
} else {
std::cout << "Draw\n";
}
}
}