Codeforces

Codeforces #763

yujaa 2022. 1. 2. 17:01

A. Robot Cleaner

Problem - A - Codeforces

 

Problem - A - Codeforces

 

codeforces.com

\(n \times m\) 사이즈의 보드판이 주어진다.

로봇의 좌표는 \((r_b, c_b)\), 목표칸의 좌표는 \((r_d, c_d)\)이다.

 

로봇은 1초마다 \((dr, dc)\)만큼 움직인다.

즉, \((r, c) \rightarrow (r+dr, c+dc)\)

 

초기 \(dr=1, dc=1\)이다.

수직벽에 닿으면 \(dc \rightarrow -dc\), 수평벽에 닿으면 \(dr \rightarrow -dr\)로 값이 변한다.

 

로봇은 다음 칸으로 이동하기 전에 현재 행과 열을 청소한다.

목표칸을 청소하기까지 몇 초가 걸리는지 구하는 문제이다.

 

가로 방향과 세로 방향을 분리해서 생각하면 편하다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <bits/stdc++.h>
using namespace std;
 
int main(void) {
    ios::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);
    
    int t; cin >> t;
    while (t--) {
        int n, m, rb, cb, rd, cd;
        cin >> n >> m >> rb >> cb >> rd >> cd;
        int ans = INT_MAX;
        if (rb <= rd) ans = min(ans, rd - rb);
        else ans = min(ans, 2*- rd - rb);
        if (cb <= cd) ans = min(ans, cd - cb);
        else ans = min(ans, 2*- cd - cb);  
        cout << ans << '\n';
    }
    return 0;
}
cs

 

 

B. Game on Ranges

Problem - B - Codeforces

 

Problem - B - Codeforces

 

codeforces.com

초기 set에는 \([1, n]\)만 들어있다.

이후 set에 남아있는 원소가 없을 때까지 다음 행위를 반복한다.

1. set에서 어떤 원소 \([l, r]\)을 선택하여 제거한다.

2. \([l, d-1]\), \([d+1, r]\)을 (존재하면) 넣는다. \((l \le d \le r)\)

 

set에 포함되었던 구간들이 모두 주어질 때, 해당 구간에서 어떤 \(d\)를 선택했는지 찾는 문제이다.

 

구간 \([l, r]\)을 \([l, -r]\)로 변형하여 vector \(v\)에 넣고 정렬한다.

\(v_i\)와 \(v_{i+1}\)의 비교를 통해 \(v_i\)에서 어떤 \(d\)를 선택했는지 알 수 있다.

1) \(l_{v_i} = l_{v_{i+1}} \Rightarrow d_{v_i} = r_{v_{i+1}} + 1\)

2) \(r_{v_i} = r_{v_{i+1}} \Rightarrow d_{v_i} = l_{v_{i+1}} - 1\)

3) \(l_{v_{i+1}} = r_{v_{i+1}} \Rightarrow d_{v_{i+1}} = l_{v_{i+1}}\)

4) 위 경우에 해당하지 않는 \(i\)는 건너뛴다.

 

그림으로 그려보면 쉽게 이해할 수 있다.

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
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<intint> pii;
 
int main(void) {
    ios::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);
    
    int t; cin >> t;
    while (t--) {
        int n; cin >> n;
        vector<pii> v(n);
        for (int i = 0; i < n; i++) {
            int l, r;
            cin >> l >> r;
            v[i] = {l, -r};
        }
        sort(v.begin(), v.end());
        
        vector<int> ans;
        for (int i = 0; i < n; i++) {
            if (i && v[i-1].first == v[i].first) {
                ans.push_back(-v[i].second + 1);
            }
            if (i && v[i-1].second == v[i].second) {
                ans.push_back(v[i].first - 1);
            }
            if (v[i].first == -v[i].second) {
                ans.push_back(v[i].first);
            }
        }
        for (int i = 0; i < n; i++) {
            cout << v[i].first << ' ' << -v[i].second << ' ' << ans[i] << '\n';
        }
    }
    return 0;
}
cs

 

 

C. Balanced Stone Heaps

Problem - C - Codeforces

 

Problem - C - Codeforces

 

codeforces.com

\(n\)개의 더미가 주어지고, \(i\)번째 더미에는 \(h_i\)개의 돌이 들어있다.

 

3번째 더미부터 \(n\)번째 더미 순서로

1. \(d (0 \le 3 \cdot d \le h_i)\)를 선택한다.

2. \(i\)번째 더미에서 \(i-1\)번째 더미로 \(d\)개의 돌을 옮긴다.

3. \(i\)번째 더미에서 \(i-2\)번째 더미로 \(2 \cdot d\)개의 돌을 옮긴다.

 

모든 과정이 끝난 후, 더미에 들어있는 돌의 최솟값의 최댓값을 구하는 문제이다.

 

파라메트릭 서치로 답을 찾을 수 있다.

판단 함수를 만들 때 주의할 점은 어떤 일이 실제로 일어나는 순서와 답을 구하는 순서가 다르다는 것이다.

돌을 옮기는 것은 3번째 더미부터지만, 돌을 얼마나 옮길지는 \(n\)번째 더미부터 결정한다.

 

\(i\)번째 더미가 다른 돌 더미들로부터 받을 수 있는 돌의 최대 개수를 \(a_i\)라고 하자.

초기에는 모든 \(i)에 대하여 \(a_i = 0\)이다.

 

\(n\)번째 더미부터 시작하여 다음 행동을 반복한다.

1. \(h_i + a_i - x < 0\)이면 \(x\)가 불가능한 값임을 알 수 있다.

2. \(d_i = \max(\lfloor \frac{h_i}{3} \rfloor , \lfloor \frac{h_i + a_i - x}{3} \rfloor)\)

3. \(a_{i-1} = a_{i-1} + d_i, \text{    } a_{i-2} = a_{i-2} + 2 \cdot d_i \)

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
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<intint> pii;
 
int n;
vector<ll> h;
 
bool ok(int x) {
    vector<ll> a(n);
    for (int i = n-1; i >= 2; i--) {
        if (h[i] + a[i] - x < 0return false;
        ll d = min(h[i]/3, (h[i] + a[i] - x)/3);
        a[i-1+= d;
        a[i-2+= 2*d;
    }
    return (h[0+ a[0>= x) && (h[1+ a[1>= x);
}
 
int main(void) {
    ios::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);
    
    int t; cin >> t;
    while (t--) {
        cin >> n;
        h.resize(n);
        for (int i = 0; i < n; i++) {
            cin >> h[i];
        }
        int lo = 0, hi = 1e9+1;
        while (lo + 1 < hi) {
            int mid = (lo + hi) / 2;
            if (ok(mid)) lo = mid;
            else hi = mid;
        }
        cout << hi - 1 << '\n';
    }
    return 0;
}
cs

'Codeforces' 카테고리의 다른 글

Codeforces #819  (0) 2022.09.26
Codeforces Educational #120  (0) 2022.01.02
Codeforces Global #18  (0) 2021.12.26
Codeforces Educational #82  (0) 2021.12.26
Codeforces #619  (0) 2021.12.23