Codeforces Round 996 (Div.2)

1月12日 Codeforces 实战记录。(1777 -> 1793)

偶遇手速场,D不会做,但学到了英语:crow 乌鸦 scarecrow 稻草人(笑

评价是这场上分纯粹因为 C 的思路快了一点,上水分了hhh。

题解

A. Two Frogs

看初始位置差,奇数Alice就被逼着走,偶数Alice追着打。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include<bits/stdc++.h>
#define int long long
using namespace std;

void solve(){
int n, a, b; cin >> n >> a >> b;
cout << ((b - a) % 2 ? "NO\n" : "YES\n");
}

signed main(){
ios::sync_with_stdio(0);
cin.tie(0);
int t; cin >> t;
while(t--) solve();
return 0;
}

B. Crafting

没有点需要加直接 YES,再看是不是有两个或以上的点需要加,有的话就直接 NO 了。

最后剩下,有一个点需要加,直接模拟。

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
37
38
39
40
41
42
43
#include<bits/stdc++.h>
#define int long long
using namespace std;

void solve(){
int n; cin >> n;
vector<int>a(n), b(n);
for(int i = 0; i < n; i++){
cin >> a[i];
}
for(int i = 0; i < n; i++){
cin >> b[i];
}
int cnt = 0, pos = -1;
for(int i = 0; i < n; i++){
if(a[i] < b[i]) cnt++, pos = i;
}
if(cnt == 0){
cout << "YES\n";
}
else if(cnt == 1){
int k = b[pos] - a[pos];
for(int i = 0; i < n; i++){
if(i == pos) continue;
if(a[i] - k < b[i]){
cout << "NO\n";
return;
}
}
cout << "YES\n";
}
else{
cout << "NO\n";
}
}

signed main(){
ios::sync_with_stdio(0);
cin.tie(0);
int t; cin >> t;
while(t--) solve();
return 0;
}

C. The Trail

应该算构造题,直接令 a = 0,维护着行列和,走一步算一个点即可。

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
37
38
39
40
41
42
43
44
45
46
47
48
#include<bits/stdc++.h>
#define int long long
using namespace std;

void solve(){
int n, m; cin >> n >> m;
string s; cin >> s;
vector<vector<int>>v(n, vector<int>(m, 0));
for(int i = 0; i < n; i++){
for(int j = 0; j < m; j++){
cin >> v[i][j];
}
}
vector<int>r(n, 0), c(m, 0);
for(int i = 0; i < n; i++){
for(int j = 0; j < m; j++){
r[i] += v[i][j];
c[j] += v[i][j];
}
}
int x = 0, y = 0;
for(int i = 0; i < n + m - 2; i++){
if(s[i] == 'D'){
v[x][y] = -r[x];
c[y] += v[x][y];
x++;
}
else{
v[x][y] = -c[y];
r[x] += v[x][y];
y++;
}
}
v[x][y] = -r[x];
for(int i = 0; i < n; i++){
for(int j = 0; j < m; j++){
cout << v[i][j] << " \n"[j == m - 1];
}
}
}

signed main(){
ios::sync_with_stdio(0);
cin.tie(0);
int t; cin >> t;
while(t--) solve();
return 0;
}

D. Scarecrow

一道非常考察观察的贪心题。

注意到,第一个 scarecrow 一定先走到 0 处,ans = a[0],此时 crow 被传送到 x = k

接下来考虑每个 scarecrow 的跳板作用:

  • 如果 crow 位置在 scarecrow 之前,考虑让这个 scare 在 ans 这一段时间内往前走,且不超过 x,然后两者相向而行。更新 ansx
  • 如果 crow 位置在 scarecrow 之后,考虑让这个 scare 在 ans 这一段时间内往后走,且不超过 x,直接更新 x 位置。

最后判有没有走到 l,没走到加上最后所需时间即可。

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
37
38
39
40
41
#include<bits/stdc++.h>
#define int long long
using namespace std;

void solve(){
int n, k, l; cin >> n >> k >> l;
k <<= 1, l <<= 1;
vector<int>a(n);
for(int i = 0; i < n; i++){
cin >> a[i];
a[i] <<= 1;
}

int ans = a[0];
int x = k;
for(int i = 1; i < n; i++){
if(a[i] > x){
a[i] = max(x, a[i] - ans);
ans += (a[i] - x) / 2;
x = (x + a[i]) / 2 + k;
}
else{
a[i] = min(x, a[i] + ans);
x = a[i] + k;
}
}

if(x < l){
ans += l - x;
}

cout << ans << '\n';
}

signed main(){
ios::sync_with_stdio(0);
cin.tie(0);
int t; cin >> t;
while(t--) solve();
return 0;
}