www.acmicpc.net/problem/3985

 

3985번: 롤 케이크

첫째 줄에 롤 케이크의 길이 L (1 ≤ L ≤ 1000)이 주어진다. 둘째 줄에는 방청객의 수 N (1 ≤ N ≤ 1000)이 주어진다. 다음 N개 줄에는 각 방청객 i가 종이에 적어낸 수 Pi와 Ki가 주어진다. (1 ≤ Pi ≤ Ki

www.acmicpc.net

가장 많은 조각을 받을 것으로 기대하고 있던 방청객의 번호는 입력으로 주어지는 l과 r의 차이가 큰 값을 출력하면 됩니다.

하지만 앞의 방청객이 원하는 조각을 받으면 뒤의 방청객은 받지 못하는 상황이 있을 수 있습니다.

 

입력으로 1번 방청객부터 N번 방청객까지 원하는 조각의 범위가 주어지면 list에 바로 방청객의 번호를 저장해줍니다.

이때 번호가 이미 저장되어있으면 저장하지 않고, 번호를 저장한 횟수를 num에 저장하여 num[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
41
42
43
44
45
46
47
48
49
50
#include <iostream>
using namespace std;
 
int list[1001], num[1001];
int L, N;
 
void func() {
    int maxlength = 0;
    int maxidx = 0;
    for (int i = 1; i <= N; i++) {
        if (maxlength < num[i]) {
            maxlength = num[i];
            maxidx = i;
        }
    }
 
    cout << maxidx << '\n';
}
 
void input() {
    int maxlength = 0;
    int maxidx = 0;
    int l, r;
    cin >> L >> N;
    for (int i = 1; i <= N; i++) {
        cin >> l >> r;
        if (maxlength < r - l) {
            maxlength = r - l;
            maxidx = i;
        }
 
        for (int j = l; j <= r; j++) {
            if (list[j]) continue;
            list[j] = i;
            num[i]++;
        }
    }
 
    cout << maxidx << '\n';
}
 
int main() {
    cin.tie(NULL); cout.tie(NULL);
    ios::sync_with_stdio(false);
 
    input();
    func();
 
    return 0;
}
cs

'algorithm > Implementation' 카테고리의 다른 글

boj 3085 사탕 게임  (0) 2021.02.26
boj 8320 직사각형을 만드는 방법  (0) 2021.02.25
boj 2116 주사위 쌓기  (0) 2021.02.25
boj 10163 색종이  (0) 2021.02.24
boj 20055 컨베이어 벨트 위의 로봇  (0) 2021.02.23

www.acmicpc.net/problem/2304

 

2304번: 창고 다각형

첫 줄에는 기둥의 개수를 나타내는 정수 N이 주어진다. N은 1 이상 1,000 이하이다. 그 다음 N 개의 줄에는 각 줄에 각 기둥의 왼쪽 면의 위치를 나타내는 정수 L과 높이를 나타내는 정수 H가 한 개의

www.acmicpc.net

이 문제와 같은 문제를 코테에서 풀었지만 삽질을 하는바람에 시간없어서 못푼 문제입니다.. ㅠ 문제보자마자 바로 생각이 나더군요...

 

그때 접근했던 풀이방법이 떠올라서 그대로 구현해보니 AC를 받았습니다. 하..

방법은 세그먼트 트리입니다.

우선 위치인 l과 높이인 h를 입력으로 받습니다.

list배열에는 인덱스가 l인 기둥의 높이를 h로 유지합니다.

입력을 받는동안 L에 최대 인덱스를 갱신하고, 트리에 구간 최댓값을 유지합니다.

 

이제 func함수에서 1 ~ L까지 높이를 구합니다.

i번째 기둥의 최종 높이는 1 ~ i의 최댓값과 i ~ L의 최댓값 중 최솟값입니다.

이 값을 list[i]에 다시 넣어줍니다.

출력은 list의 누적합(1 ~ 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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
 
#include <iostream>
#include <algorithm>
using namespace std;
 
int tree[4004], list[1001];
int N, L, ans;
 
int init(int node, int s, int e) {
    if (s == e) return tree[node] = list[s];
 
    int m = (s + e) / 2;
    return tree[node] = max(init(node * 2, s, m), init(node * 2 + 1, m + 1, e));
}
 
int query(int node, int s, int e, int l, int r) {
    if (l > e || s > r) return 0;
    if (l <= s && e <= r) return tree[node];
 
    int m = (s + e) / 2;
    return max(query(node * 2, s, m, l, r), query(node * 2 + 1, m + 1, e, l, r));
}
 
void func() {
    for (int i = 1; i <= L; i++) {
        int l = query(11, L, 1, i);
        int r = query(11, L, i, L);
 
        list[i] = min(l, r);
 
        ans += list[i];
    }
 
    cout << ans << '\n';
}
 
void input() {
    int l, h;
    cin >> N;
    for (int i = 0; i < N; i++) {
        cin >> l >> h;
        list[l] = h;
        L = max(L, l);
    }
    init(11, L);
}
 
int main() {
    cin.tie(NULL); cout.tie(NULL);
    ios::sync_with_stdio(false);
 
    input();
    func();
 
    return 0;
}
cs

'algorithm > SegmentTree' 카테고리의 다른 글

boj 1849 순열  (0) 2021.09.08
boj 14719 빗물  (0) 2021.03.15
boj 14438 수열과 쿼리 17  (0) 2021.02.21
boj 13537 수열과 쿼리 1  (0) 2021.02.21
boj 6549 히스토그램에서 가장 큰 직사각형  (0) 2021.02.19

www.acmicpc.net/problem/2116

 

2116번: 주사위 쌓기

첫줄에는 주사위의 개수가 입력된다. 그 다음 줄부터는 한 줄에 하나씩 주사위의 종류가 1번 주사위부터 주사위 번호 순서대로 입력된다. 주사위의 종류는 각 면에 적혀진 숫자가 그림1에 있는

www.acmicpc.net

주사위를 순서대로 쌓는데 i번 주사위의 윗면의 숫자와 i + 1번 주사위의 아랫면 숫자가 같아야합니다.

우선 rlist에 반대편 인덱스를 모두 저장해줍니다.

그 다음 0 ~ 5번 인덱스가 밑면일 경우를 다 구해서 각각의 최댓값을 갱신시켜주면 됩니다.

 

i번이 맨밑 인덱스라고 하면 반대 인덱스인 rx를 가져올수 있고, 이 두개를 제외한 나머지 숫자 중 max값을 찾아서 다음 인덱스로 재귀를 돌려주시면 됩니다.

이때 재귀를 돌릴 때 유지하는 값은 인덱스, 위에있는 값 (맞춰야하는 값), 현재까지 주사위의 최대 합입니다.

 

 

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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
 
int list[10000][6], rlist[6];
int N, ans;
 
void init() {
    rlist[0= 5;
    rlist[5= 0;
 
    rlist[1= 3;
    rlist[3= 1;
 
    rlist[2= 4;
    rlist[4= 2;
}
 
void dfs(int idx, int value, int sum) {
    if (idx == N) {
        ans = max(ans, sum);
        return;
    }
 
    for (int i = 0; i < 6; i++) {
        if (list[idx][i] == value) {
            int rx = rlist[i];
 
            int max_value = 0;
            for (int j = 0; j < 6; j++) {
                if (j == i || j == rx) continue;
 
                max_value = max(max_value, list[idx][j]);
            }
 
            dfs(idx + 1, list[idx][rx], sum + max_value);
            break;
        }
    }
}
 
void func() {
    for (int i = 0; i < 6; i++) {
        int rx = rlist[i];
 
        int max_value = 0;
        for (int j = 0; j < 6; j++) {
            if (j == i || j == rx) continue;
 
            max_value = max(max_value, list[0][j]);
        }
 
        dfs(1, list[0][rx], max_value);
    }
}
 
void input() {
    cin >> N;
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < 6; j++cin >> list[i][j];
    }
}
 
int main() {
    cin.tie(NULL); cout.tie(NULL);
    ios::sync_with_stdio(false);
 
    init();
    input();
    func();
    cout << ans << '\n';
 
    return 0;
}
cs

'algorithm > Implementation' 카테고리의 다른 글

boj 8320 직사각형을 만드는 방법  (0) 2021.02.25
boj 3985 롤 케이크  (0) 2021.02.25
boj 10163 색종이  (0) 2021.02.24
boj 20055 컨베이어 벨트 위의 로봇  (0) 2021.02.23
boj 2331 반복수열  (0) 2021.02.23

www.acmicpc.net/problem/10163

 

10163번: 색종이

평면에 색깔이 서로 다른 직사각형 모양의 색종이 N장이 하나씩 차례로 놓여진다. 이때 색종이가 비스듬하게 놓이는 경우는 없다. 즉, 모든 색종이의 변은 서로 평행하거나, 서로 수직이거나 둘

www.acmicpc.net

입력으로 x시작좌표(sx), y시작좌표(sy), 너비(width), 높이(height)가 주어집니다.

list배열에 (sx, sy) ~ (sx + width, sy + height)만큼 번호인 i를 넣어줍니다.

만약 list[x][y]에 값이 있으면 덮어씌우므로 num[이전의 번호]--를 해줘야합니다.

 

 

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 <iostream>
using namespace std;
 
int list[101][101], num[101];
int N;
 
void print() {
    for (int i = 1; i <= N; i++) {
        cout << num[i] << '\n';
    }
}
 
void input() {
    int sx, sy, width, height;
    cin >> N;
    for (int i = 1; i <= N; i++) {
        cin >> sx >> sy >> width >> height;
        for (int x = sx; x < sx + width; x++) {
            for (int y = sy; y < sy + height; y++) {
                if (list[x][y]) {
                    num[list[x][y]]--;
                }
                list[x][y] = i;
                num[list[x][y]]++;
            }
        }
    }
}
 
int main() {
    cin.tie(NULL); cout.tie(NULL);
    ios::sync_with_stdio(false);
 
    input();
    print();
 
    return 0;
}
cs

 

'algorithm > Implementation' 카테고리의 다른 글

boj 3985 롤 케이크  (0) 2021.02.25
boj 2116 주사위 쌓기  (0) 2021.02.25
boj 20055 컨베이어 벨트 위의 로봇  (0) 2021.02.23
boj 2331 반복수열  (0) 2021.02.23
boj 10157 자리배정  (0) 2021.02.17

www.acmicpc.net/problem/16922

 

16922번: 로마 숫자 만들기

2, 6, 10, 11, 15, 20, 51, 55, 60, 100을 만들 수 있다.

www.acmicpc.net

1, 5, 10, 50을 배열에 넣어놓고 조합으로 해결하였습니다.

인덱스와 갯수와 합을 유지시키면서 재귀를 돌려줍니다.

N개를 뽑으면 숫자를 저장하였는데 이 때 중복된 값을 넣으면 안되므로 set에 넣어줍니다.

함수가 끝나고 최종 set의 크기를 출력하시면 됩니다.

 

 

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
#include <iostream>
#include <set>
using namespace std;
 
set<int> s;
int list[4];
int N;
 
void init() {
    list[0= 1;
    list[1= 5;
    list[2= 10;
    list[3= 50;
}
 
void func(int idx, int cnt, int sum) {
    if (cnt == N) {
        if (sum > 0) s.insert(sum);
        return;
    }
 
    for (int i = idx; i < 4; i++) {
        func(i, cnt + 1, sum + list[i]);
    }
}
 
int main() {
    cin.tie(NULL); cout.tie(NULL);
    ios::sync_with_stdio(false);
 
    cin >> N;
    init();
    func(000);
    cout << s.size() << '\n';
 
    return 0;
}
cs

'algorithm > dfs' 카테고리의 다른 글

boj 2023 신기한 소수  (0) 2021.03.16
boj 14500 테트로미노  (0) 2021.03.15
boj 1987 알파벳  (0) 2021.02.18
boj 3109 빵집  (0) 2021.02.18
boj 17406 배열 돌리기 4  (0) 2021.02.10

www.acmicpc.net/problem/20055

 

20055번: 컨베이어 벨트 위의 로봇

길이가 N인 컨베이어 벨트가 있고, 길이가 2N인 벨트가 이 컨베이어 벨트를 위아래로 감싸며 돌고 있다. 벨트는 길이 1 간격으로 2N개의 칸으로 나뉘어져 있으며, 각 칸에는 아래 그림과 같이 1부

www.acmicpc.net

1번 칸 - 로봇이 올라가는 위치

N번 칸 - 로봇이 내려가는 위치

 

로봇은 무조건 1번 칸에만 놓아야하며, 컨베이어 벨트에서의 이동은 가능합니다.

 

컨베이어 벨트를 이용하여 로봇들을 옮기는 과정은

1. 벨트가 한 칸 회전합니다.

2. 벨트에 로봇이 올라가있으면 회전하는 방향으로 한 칸 이동할 수 있으면 이동합니다.

3. 로봇이 이동한 칸의 내구도가 1 감소합니다.

4. 올라가는 위치(1번 칸)에 로봇이 없고, 내구도가 0이 아니면 로봇을 하나 올립니다.

5. 로봇이 올라가면서 올라가는 위치(1번 칸)의 내구도가 1 감소합니다.

6. 내구도가 0인 칸의 갯수가 K개 이상이면 과정을 종료, 아니면 1번부터 다시 수행합니다.

7. 과정이 종료되면 t를 출력합니다.

 

두 가지 방법으로 해결하였는데

첫 번째는 벡터(C++)와 연결리스트(Java)를 이용하여 컨베이어 벨트를 직접 옮긴 후에 로봇 이동

두 번째는 올라가는 위치와 내려가는 위치를 인덱스로만 유지하고 로봇 이동

당연히 두 번째방법이 훨씬 효율적이었습니다. 업로드는 두 가지 모두 업로드하겠습니다.

 

벡터와 연결리스트를 이용한 방법입니다.

저는 벡터를 사용하여 칸의 내구도, 로봇의 존재여부를 저장하였습니다.

컨베이어 벨트가 이동하는 것은 벡터의 마지막 요소를 begin()에 넣어주었고,

N ~ 1번 칸까지 역순으로 컨베이어 벨트 위에있는 모든 로봇을 이동시켜주었습니다.

그 다음 1번 칸에 로봇을 놓았고 이 과정에서 칸의 내구도가 0이되면 ans를 1증가하였습니다.

반복문 마지막에 ans가 K 이상인지 확인하였고, 이상이면 t를 출력하고 리턴, 아니면 계속 반복문을 돌려주었습니다.

 

그 다음은 인덱스를 유지한 방법입니다.

l = 1

r = N

으로 시작하고 컨베이어 이동 시마다 1씩 빼줍니다. (0이되면 2 * N으로)

그 다음 r부터 l까지 역순으로 컨베이어 벨트 위에있는 모든 로봇을 이동시켜줍니다.

그 다음 l번 칸에 로봇을 놓고 내구도를 감소시킵니다.

이 과정에서 내구도가 0이되면 ans++, ans가 K 이상이면 t를 출력합니다.

 

Java LinkedList를 이용한 방법
Java 인덱스를 이동한 방법

 

로직은 같으나 컨베이어 이동을 시뮬레이션으로 직접 이동시키냐, 인덱스만 이동시키냐에 따라 시간 차이가 크게남을 확인하였습니다.

 

 

[벡터 이용한 풀이]

[C++]

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
49
50
51
52
53
54
55
56
57
58
#include <iostream>
#include <vector>
using namespace std;
 
vector<pair<intint> > list;
int N, K, ans;
 
void func() {
    for (int t = 1; ; t++) {
        list.insert(list.begin(), list[2 * N - 1]);
        list.pop_back();
 
        for (int i = N - 1; i >= 0; i--) {
            if (i == N - 1) {
                list[i].second = 0;
                continue;
            }
            if (!list[i].second) continue;
            if (!list[i + 1].first || list[i + 1].second) continue;
 
            if (i + 1 != N - 1) list[i + 1].second = 1;
            list[i].second = 0;
            list[i + 1].first--;
 
            if (!list[i + 1].first) ans++;
        }
 
        if (list[0].first) {
            list[0].second = 1;
            list[0].first--;
            if (!list[0].first) ans++;
        }
 
        if (ans >= K) {
            cout << t << '\n';
            break;
        }
    }
}
 
void input() {
    int x;
    cin >> N >> K;
    for (int i = 1; i <= 2 * N; i++) {
        cin >> x;
        list.push_back({ x, 0 });
    }
}
 
int main() {
    cin.tie(NULL); cout.tie(NULL);
    ios::sync_with_stdio(false);
 
    input();
    func();
 
    return 0;
}
cs

 

[Java]

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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.StringTokenizer;
 
public class Main {
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static StringTokenizer st;
    static LinkedList<int[]> list = new LinkedList<>();
    static int N, K, ans;
 
    static void func() {
        for (int t = 1;; t++) {
            list.addFirst(list.pollLast());
 
            for (int i = N - 1; i >= 0; i--) {
                if (i == N - 1) {
                    list.get(i)[1= 0;
                    continue;
                }
                if (list.get(i)[1== 0)
                    continue;
                if (list.get(i + 1)[0== 0 || list.get(i + 1)[1!= 0)
                    continue;
 
                if (i + 1 != N - 1)
                    list.get(i + 1)[1= 1;
                list.get(i)[1= 0;
                list.get(i + 1)[0]--;
                if (list.get(i + 1)[0== 0)
                    ans++;
            }
 
            if (list.get(0)[0> 0) {
                list.get(0)[0]--;
                list.get(0)[1= 1;
                if (list.get(0)[0== 0)
                    ans++;
            }
 
            if (ans >= K) {
                System.out.println(t);
                break;
            }
        }
    }
 
    static void input() throws Exception {
        int x;
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        K = Integer.parseInt(st.nextToken());
 
        st = new StringTokenizer(br.readLine());
        for (int i = 0; i < 2 * N; i++) {
            x = Integer.parseInt(st.nextToken());
            list.addLast(new int[] { x, 0 });
        }
    }
 
    public static void main(String[] args) throws Exception {
        input();
        func();
    }
}
cs

 

[인덱스 유지]

 

[C++]

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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#include <iostream>
using namespace std;
 
pair<intint> list[201];
int N, K, ans;
 
void func() {
    int l = 1;
    int r = N;
    for (int t = 1; ; t++) {
        l--;
        r--;
        if (!l) l = 2 * N;
        if (!r) r = 2 * N;
 
        for (int i = r; ; i--) {
            if (!i) i = 2 * N;
            if (i == r) {
                list[i].second = 0;
                continue;
            }
            int next = i + 1;
            if (next == 2 * N + 1) next = 1;
            
            if (!list[i].second) {
                if (i == l) break;
                continue;
            }
            if (!list[next].first || list[next].second) {
                if (i == l) break;
                continue;
            }
 
            if (next != r) list[next].second = 1;
            list[i].second = 0;
            list[next].first--;
 
            if (!list[next].first) ans++;
            
            if (i == l) break;
        }
 
        if (list[l].first) {
            list[l].second = 1;
            list[l].first--;
            if (!list[l].first) ans++;
        }
 
        if (ans >= K) {
            cout << t << '\n';
            break;
        }
    }
}
 
void input() {
    int x;
    cin >> N >> K;
    for (int i = 1; i <= 2 * N; i++) {
        cin >> list[i].first;
    }
}
 
int main() {
    cin.tie(NULL); cout.tie(NULL);
    ios::sync_with_stdio(false);
 
    input();
    func();
 
    return 0;
}
cs

 

 

[Java]

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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
 
public class Main {
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static StringTokenizer st;
    static int list[][];
    static int N, K, ans;
 
    static void func() {
        int l = 1;
        int r = N;
        for (int t = 1;; t++) {
 
            l--;
            r--;
            if (l == 0)
                l = 2 * N;
            if (r == 0)
                r = 2 * N;
 
            for (int i = r;; i--) {
                if (i == 0)
                    i = 2 * N;
                if (i == r) {
                    list[i][1= 0;
                    continue;
                }
                int next = i + 1;
                if (next == 2 * N + 1)
                    next = 1;
 
                if (list[i][1== 0) {
                    if (i == l)
                        break;
                    continue;
                }
                if (list[next][0== 0 || list[next][1== 1) {
                    if (i == l)
                        break;
                    continue;
                }
 
                if (next != r)
                    list[next][1= 1;
                list[i][1= 0;
                list[next][0]--;
 
                if (list[next][0== 0)
                    ans++;
 
                if (i == l)
                    break;
            }
 
            if (list[l][0> 0) {
                list[l][1= 1;
                list[l][0]--;
                if (list[l][0== 0)
                    ans++;
            }
 
            if (ans >= K) {
                System.out.println(t);
                break;
            }
        }
    }
 
    static void input() throws Exception {
        int x;
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        K = Integer.parseInt(st.nextToken());
        list = new int[2 * N + 1][2];
 
        st = new StringTokenizer(br.readLine());
        for (int i = 1; i <= 2 * N; i++) {
            list[i][0= Integer.parseInt(st.nextToken());
        }
    }
 
    public static void main(String[] args) throws Exception {
        input();
        func();
    }
}
cs

 

'algorithm > Implementation' 카테고리의 다른 글

boj 2116 주사위 쌓기  (0) 2021.02.25
boj 10163 색종이  (0) 2021.02.24
boj 2331 반복수열  (0) 2021.02.23
boj 10157 자리배정  (0) 2021.02.17
boj 16918 봄버맨  (0) 2021.02.17

www.acmicpc.net/problem/2331

 

2331번: 반복수열

첫째 줄에 반복되는 부분을 제외했을 때, 수열에 남게 되는 수들의 개수를 출력한다.

www.acmicpc.net

D[1] = A

D[n] = D[n - 1]의 각 자리의 숫자를 M번 곱한 수(각 자리마다 ^M)들의 합입니다.

 

전 재귀를 돌려가면서 현재 숫자와 수열의 갯수를 유지하였습니다.

일의자리부터 pow(tmp, M)한 값을 next에 차례대로 더해줍니다.

next가 set에 있는 값이면 cyclestart에 next를 넣어주고 리턴합니다.

(예외처리로 D[n] = D[n - 1] 즉, 자신 다음이 자신일 경우가 있어 처리해주었습니다.)

 

재귀를 빠져나오면서 num == cyclestart이면 ans에 cnt - 1을 넣어주어 출력하였습니다.

 

 

[C++]

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
#include <iostream>
#include <set>
#include <cmath>
using namespace std;
 
set<int> s;
int N, M, cyclestart, ans;
 
void func(int num, int cnt) {
    s.insert(num);
 
    int n = num;
    int next = 0;
    while (1) {
        int tmp = n % 10;
        tmp = pow(tmp, M);
        next += tmp;
        n /= 10;
        if (!n) break;
    }
 
    if (s.find(next) != s.end()) {
        cyclestart = next;
        if (cyclestart == num) ans = cnt - 1;
        return;
    }
 
    func(next, cnt + 1);
    if (num == cyclestart)
        ans = cnt - 1;
}
 
int main() {
    cin.tie(NULL); cout.tie(NULL);
    ios::sync_with_stdio(false);
 
    cin >> N >> M;
    func(N, 1);
    cout << ans << '\n';
    
    return 0;
}
cs

 

 

[Java]

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
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.HashSet;
import java.util.Set;
import java.util.StringTokenizer;
 
public class Main {
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static StringTokenizer st;
    static Set<Integer> s = new HashSet<>();
    static int N, M, cyclestart, ans;
 
    static void func(int num, int cnt) {
        s.add(num);
 
        int next = 0;
        int n = num;
        while (true) {
            next += Math.pow(n % 10, M);
            n /= 10;
            if (n == 0)
                break;
        }
 
        if (s.contains(next)) {
            if (next == num)
                ans = cnt - 1;
            cyclestart = next;
            return;
        }
 
        func(next, cnt + 1);
        if (cyclestart == num)
            ans = cnt - 1;
    }
 
    static void input() throws Exception {
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());
    }
 
    public static void main(String[] args) throws Exception {
        input();
        func(N, 1);
        System.out.println(ans);
    }
}
cs

'algorithm > Implementation' 카테고리의 다른 글

boj 10163 색종이  (0) 2021.02.24
boj 20055 컨베이어 벨트 위의 로봇  (0) 2021.02.23
boj 10157 자리배정  (0) 2021.02.17
boj 16918 봄버맨  (0) 2021.02.17
boj 16935 배열 돌리기 3  (0) 2021.02.10

www.acmicpc.net/problem/1826

 

1826번: 연료 채우기

첫째 줄에 주유소의 개수 N(1 ≤ N ≤ 10,000)가 주어지고 두 번째 줄부터 N+1번째 줄 까지 주유소의 정보가 주어진다. 주유소의 정보는 두개의 정수 a,b로 이루어 져 있는데 a(1 ≤ a ≤ 1,000,000)는 성경

www.acmicpc.net

1km를 가는데 연료가 1L씩 소모됩니다.

목적지까지 가는 길에 주유소가 있어서 부족한 연료를 채우고 가야합니다.

마을에 도착했을 때, 주유소를 방문한 최소 횟수를 출력하는 문제입니다. 만약 목적지에 도착하지 못하면 -1을 출력합니다.

 

저는 거리 1당 1L이므로 연료소모를 하지않고 계속 쌓으면서 목적지까지 갈 수 있는지 확인하였고, 방법은 그리디로 하였습니다.

우선 입력으로 주어지는 주유소의 정보를 거리기준으로 오름차순 정렬합니다.

그 다음 현재 연료로 갈 수 있는 지점까지 큐에 넣어주면서 이동하다가

연료보다 더 멀리있는 주유소가 나오면 지금까지 큐에 넣어두었던 연료 중 가장 높은 값을 저장합니다.

물론 이를 위해 우선순위 큐를 사용합니다.

 

이 연산을 반복하여 마지막 목적지를 기준으로 연료가 충분한지도 확인해야합니다.

충분하면 그대로 ans를 출력, 모든 주유소를 다 들려도 목적지에 가지 못하면 -1을 출력합니다.

 

 

[C++]

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
49
50
51
52
53
54
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
 
priority_queue<int> q;
pair<intint> list[10001];
int N, des, now, ans;
 
void func() {
    int idx = 0;
    while (idx < N) {
        if (now >= list[idx].first) {
            q.push(list[idx].second);
        }
        else {
            if (q.empty()) break;
            now += q.top();
            q.pop();
            ans++;
            idx--;
        }
        idx++;
    }
    while (!q.empty()) {
        if (now >= des) break;
        
        now += q.top();
        q.pop();
        ans++;
    }
 
    if (now >= des) cout << ans << '\n';
    else cout << "-1\n";
}
 
void input() {
    cin >> N;
    for (int i = 0; i < N; i++) {
        cin >> list[i].first >> list[i].second;
    }
    cin >> des >> now;
    sort(list, list + N);
}
 
int main() {
    cin.tie(NULL); cout.tie(NULL);
    ios::sync_with_stdio(false);
 
    input();
    func();
 
    return 0;
}
cs

 

 

[Java]

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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.Comparator;
import java.util.PriorityQueue;
import java.util.StringTokenizer;
 
public class Main {
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static StringTokenizer st;
    static int list[][];
    static int N, des, now, ans;
 
    static void func() {
        PriorityQueue<Integer> q = new PriorityQueue<>();
        int idx = 0;
        while (idx < N) {
            if (now >= list[idx][0])
                q.add(-list[idx][1]);
            else {
                if (q.isEmpty())
                    break;
 
                now -= q.poll();
                ans++;
                idx--;
            }
            idx++;
        }
 
        while (!q.isEmpty()) {
            if (now >= des)
                break;
            now -= q.poll();
            ans++;
        }
 
        if (now >= des)
            System.out.println(ans);
        else
            System.out.println(-1);
    }
 
    static void input() throws Exception {
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        list = new int[N][2];
        for (int i = 0; i < N; i++) {
            st = new StringTokenizer(br.readLine());
            list[i][0= Integer.parseInt(st.nextToken());
            list[i][1= Integer.parseInt(st.nextToken());
        }
        st = new StringTokenizer(br.readLine());
        des = Integer.parseInt(st.nextToken());
        now = Integer.parseInt(st.nextToken());
 
        Arrays.sort(list, new Comparator<int[]>() {
            @Override
            public int compare(int[] a, int[] b) {
                return a[0- b[0];
            }
        });
    }
 
    public static void main(String[] args) throws Exception {
        input();
        func();
    }
}
cs

'algorithm > Greedy' 카테고리의 다른 글

boj 2262 토너먼트 만들기  (0) 2021.10.16
boj 13904 과제  (0) 2021.09.30
boj 8980 택배  (0) 2021.02.16
boj 11000 강의실 배정  (0) 2021.02.16
boj 1931 회의실 배정  (0) 2021.02.16

www.acmicpc.net/problem/15653

 

15653번: 구슬 탈출 4

첫 번째 줄에는 보드의 세로, 가로 크기를 의미하는 두 정수 N, M (3 ≤ N, M ≤ 10)이 주어진다. 다음 N개의 줄에 보드의 모양을 나타내는 길이 M의 문자열이 주어진다. 이 문자열은 '.', '#', 'O', 'R', 'B'

www.acmicpc.net

보드를 4방향으로 기울여 구슬을 구멍으로 빼내는데 걸리는 최소 횟수를 출력하는 문제입니다. 구멍을 통해 빼낼 수 없으면 -1을 출력합니다.

 

시뮬레이션으로 구슬을 이동시켜야하며, 4방향으로 기울이는 것은 bfs를 이용하였습니다.

우선 큐에 입력으로 받은 빨간 구슬의 좌표, 파란 구슬의 좌표, 그리고 0(움직인 횟수)를 넣습니다.

그 다음 bfs로 구슬을 움직여줍니다.

 

구슬을 움직일 때는

1. 빨간 구슬과 파란 구슬을 벽이나 구멍이 있을때까지 움직여줍니다.

2. 만약 파란 구슬이 도중에 탈출했다면 continue (파란 구슬은 탈출하면 안됩니다.)

3. 파란 구슬이 탈출 안했고, 빨간 구슬이 탈출 했으면 cnt + 1 출력

4. 둘 다 탈출 못했으면 큐에 넣기 전에 구슬들이 겹칠 가능성이 존재하므로 확인해줍니다.

5. 구슬들이 겹쳐있으면 원래의 자리와 거리를 구해 먼 쪽이 한칸 뒤로 이동합니다.

6. 이제 다음 칸인 (nrx, nry), (nbx, nby)의 방문했는지 확인해줍니다.

7. 모두 통과되면 방문 체크를 해주고, 큐에 넣어줍니다.

8. 만약 큐가 비어있게 되면 탈출을 못했다는 뜻이므로 -1을 출력해줍니다.

 

백준에 있는 구슬 탈출 문제가 여러개 있는데 똑같은 문제인것 같네요

 

 

[C++]

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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
 
typedef struct point {
    int rx;
    int ry;
    int bx;
    int by;
    int cnt;
}point;
 
queue<point> q;
bool visit[11][11][11][11];
char list[11][11];
int direct[4][2= { {0,1},{1,0},{0,-1},{-1,0} };
int N, M;
 
void bfs() {
    while (!q.empty()) {
        int rx = q.front().rx;
        int ry = q.front().ry;
        int bx = q.front().bx;
        int by = q.front().by;
        int cnt = q.front().cnt;
        q.pop();
        
        for (int i = 0; i < 4; i++) {
            int nrx = rx;
            int nry = ry;
 
            bool redchk = false;
            bool bluechk = false;
            while (1) {
                nrx += direct[i][0];
                nry += direct[i][1];
 
                if (list[nrx][nry] == '#') {
                    nrx -= direct[i][0];
                    nry -= direct[i][1];
                    break;
                }
                else if (list[nrx][nry] == 'O') {
                    redchk = true;
                    break;
                }
            }
 
            int nbx = bx;
            int nby = by;
 
            while (1) {
                nbx += direct[i][0];
                nby += direct[i][1];
 
                if (list[nbx][nby] == '#') {
                    nbx -= direct[i][0];
                    nby -= direct[i][1];
                    break;
                }
                else if (list[nbx][nby] == 'O') {
                    bluechk = true;
                    break;
                }
            }
 
            if (bluechk) continue;
            else if (redchk) {
                cout << cnt + 1 << '\n';
                return;
            }
 
            if (nrx == nbx && nry == nby) {
                int reddis = abs(nrx - rx) + abs(nry - ry);
                int bluedis = abs(nbx - bx) + abs(nby - by);
 
                if (reddis > bluedis) {
                    nrx -= direct[i][0];
                    nry -= direct[i][1];
                }
                else {
                    nbx -= direct[i][0];
                    nby -= direct[i][1];
                }
            }
 
            if (visit[nrx][nry][nbx][nby]) continue;
 
            q.push({ nrx,nry,nbx,nby,cnt + 1 });
            visit[nrx][nry][nbx][nby] = true;
        }
    }
 
    cout << "-1\n";
}
 
void input() {
    int rx, ry, bx, by;
    cin >> N >> M;
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < M; j++) {
            cin >> list[i][j];
            if (list[i][j] == 'B') {
                bx = i;
                by = j;
            }
            else if (list[i][j] == 'R') {
                rx = i;
                ry = j;
            }
        }
    }
 
    q.push({ rx,ry,bx,by,0 });
    visit[rx][ry][bx][by] = true;
}
 
int main() {
    cin.tie(NULL); cout.tie(NULL);
    ios::sync_with_stdio(false);
 
    input();
    bfs();
 
    return 0;
}
cs

 

 

[Java]

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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.StringTokenizer;
 
public class Main {
    static class Pair {
        int rx;
        int ry;
        int bx;
        int by;
        int cnt;
 
        public Pair(int rx, int ry, int bx, int by, int cnt) {
            this.rx = rx;
            this.ry = ry;
            this.bx = bx;
            this.by = by;
            this.cnt = cnt;
        }
    }
 
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static StringTokenizer st;
    static Deque<Pair> dq = new ArrayDeque<>();
    static boolean visit[][][][] = new boolean[11][11][11][11];
    static char list[][] = new char[11][11];
    static int direct[][] = { { 01 }, { 10 }, { 0-1 }, { -10 } };
    static int N, M;
 
    static void bfs() {
        while (!dq.isEmpty()) {
            int rx = dq.peek().rx;
            int ry = dq.peek().ry;
            int bx = dq.peek().bx;
            int by = dq.peek().by;
            int cnt = dq.poll().cnt;
 
            for (int i = 0; i < 4; i++) {
                int nrx = rx;
                int nry = ry;
                boolean redchk = false;
                while (true) {
                    nrx += direct[i][0];
                    nry += direct[i][1];
 
                    if (list[nrx][nry] == '#') {
                        nrx -= direct[i][0];
                        nry -= direct[i][1];
                        break;
                    }
                    if (list[nrx][nry] == 'O') {
                        redchk = true;
                        break;
                    }
                }
 
                int nbx = bx;
                int nby = by;
                boolean bluechk = false;
                while (true) {
                    nbx += direct[i][0];
                    nby += direct[i][1];
 
                    if (list[nbx][nby] == '#') {
                        nbx -= direct[i][0];
                        nby -= direct[i][1];
                        break;
                    }
                    if (list[nbx][nby] == 'O') {
                        bluechk = true;
                        break;
                    }
                }
 
                if (bluechk)
                    continue;
                else if (redchk) {
                    System.out.println(cnt + 1);
                    return;
                }
 
                if (nrx == nbx && nry == nby) {
                    int reddis = Math.abs(nrx - rx) + Math.abs(nry - ry);
                    int bluedis = Math.abs(nbx - bx) + Math.abs(nby - by);
 
                    if (bluedis < reddis) {
                        nrx -= direct[i][0];
                        nry -= direct[i][1];
                    } else {
                        nbx -= direct[i][0];
                        nby -= direct[i][1];
                    }
                }
 
                if (visit[nrx][nry][nbx][nby])
                    continue;
 
                dq.add(new Pair(nrx, nry, nbx, nby, cnt + 1));
                visit[nrx][nry][nbx][nby] = true;
            }
        }
 
        System.out.println(-1);
    }
 
    static void input() throws Exception {
        int rx = 0, ry = 0, bx = 0, by = 0;
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());
        for (int i = 0; i < N; i++) {
            st = new StringTokenizer(br.readLine());
            list[i] = st.nextToken().toCharArray();
            for (int j = 0; j < M; j++) {
                if (list[i][j] == 'R') {
                    rx = i;
                    ry = j;
                } else if (list[i][j] == 'B') {
                    bx = i;
                    by = j;
                }
            }
        }
 
        dq.add(new Pair(rx, ry, bx, by, 0));
        visit[rx][ry][bx][by] = true;
    }
 
    public static void main(String[] args) throws Exception {
        input();
        bfs();
    }
}
cs

'algorithm > bfs' 카테고리의 다른 글

boj 2589 보물섬  (0) 2021.03.16
boj 11559 Puyo Puyo  (0) 2021.02.26
boj 1525 퍼즐  (0) 2021.02.19
boj 7576 토마토  (0) 2021.02.19
boj 17135 캐슬 디펜스  (0) 2021.02.17

www.acmicpc.net/problem/17299

 

17299번: 오등큰수

첫째 줄에 수열 A의 크기 N (1 ≤ N ≤ 1,000,000)이 주어진다. 둘째에 수열 A의 원소 A1, A2, ..., AN (1 ≤ Ai ≤ 1,000,000)이 주어진다.

www.acmicpc.net

emoney96.tistory.com/49

 

boj 17298 오큰수

www.acmicpc.net/problem/17298 17298번: 오큰수 첫째 줄에 수열 A의 크기 N (1 ≤ N ≤ 1,000,000)이 주어진다. 둘째에 수열 A의 원소 A1, A2, ..., AN (1 ≤ Ai ≤ 1,000,000)이 주어진다. www.acmicpc.net 스..

emoney96.tistory.com

위의 문제와 같은 문제입니다.

오큰수는 오른쪽에 있는 자신보다 큰 수 중에 가장 왼쪽에 있는 수를 출력하는 문제이고, 

이 문제는 오른쪽에 있는 자신보다 등장횟수가 많은 수 중에 가장 왼쪽에 있는 수를 출력하는 문제입니다.

자신보다 큰 수 -> 자신보다 등장횟수가 많은 수 의 차이이며 풀이는 같습니다.

 

이 문제 역시 수열을 역순으로 탐색하였고,

list[i]를 스택에 넣기 전에 자신보다 등장횟수가 적은 값들을 모두 pop해줍니다.

 

스택이 비어있으면 -1, 아니면 top을 출력해주시면 됩니다.

 

 

[C++]

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
#include <iostream>
#include <stack>
using namespace std;
 
stack<int> s;
int list[1000001], num[1000001], ans[1000001];
int N;
 
void print() {
    for (int i = 1; i <= N; i++) {
        cout << ans[i] << ' ';
    }
 
    cout << '\n';
}
 
void func() {
    for (int i = N; i > 0; i--) {
        while (!s.empty() && num[list[i]] >= num[s.top()]) s.pop();
 
        if (s.empty()) ans[i] = -1;
        else ans[i] = s.top();
 
        s.push(list[i]);
    }
}
 
void input() {
    cin >> N;
    for (int i = 1; i <= N; i++) {
        cin >> list[i];
        num[list[i]]++;
    }
}
 
int main() {
    cin.tie(NULL); cout.tie(NULL);
    ios::sync_with_stdio(false);
 
    input();
    func();
    print();
 
    return 0;
}
cs

 

 

[Java]

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
49
50
51
52
53
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Stack;
import java.util.StringTokenizer;
 
public class Main {
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static StringTokenizer st;
    static Stack<Integer> s = new Stack<>();
    static int list[], num[], ans[];
    static int N;
 
    static void print() {
        StringBuffer sb = new StringBuffer();
        for (int i = 1; i <= N; i++)
            sb.append(ans[i]).append(" ");
        System.out.println(sb.toString());
    }
 
    static void func() {
        for (int i = N; i > 0; i--) {
            while (!s.isEmpty() && num[list[i]] >= num[s.peek()])
                s.pop();
 
            if (s.isEmpty())
                ans[i] = -1;
            else
                ans[i] = s.peek();
 
            s.push(list[i]);
        }
    }
 
    static void input() throws Exception {
        st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        list = new int[N + 1];
        num = new int[1000001];
        ans = new int[1000001];
 
        st = new StringTokenizer(br.readLine());
        for (int i = 1; i <= N; i++) {
            list[i] = Integer.parseInt(st.nextToken());
            num[list[i]]++;
        }
    }
 
    public static void main(String[] args) throws Exception {
        input();
        func();
        print();
    }
}
cs

'algorithm > data-structure' 카테고리의 다른 글

boj 15926 현욱은 괄호왕이야!!  (1) 2023.07.24
boj 21939 문제 추천 시스템 Version 1  (0) 2022.02.11
boj 9372 상근이의 여행  (0) 2021.02.09
boj 1158 요세푸스 문제  (0) 2021.02.09
boj 1918 후위 표기식  (0) 2021.02.05

www.acmicpc.net/problem/14438

 

14438번: 수열과 쿼리 17

길이가 N인 수열 A1, A2, ..., AN이 주어진다. 이때, 다음 쿼리를 수행하는 프로그램을 작성하시오. 1 i v : Ai를 v로 바꾼다. (1 ≤ i ≤ N, 1 ≤ v ≤ 109) 2 i j : Ai, Ai+1, ..., Aj에서 크기가 가장 작은 값을

www.acmicpc.net

1 i v -> i번째 수를 v로 바꿉니다.

2 i j -> i ~ j 번째 수들 중에서 가장 작은 값을 출력합니다.

 

배열의 원소를 입력받을 때마다 세그먼트 트리로 최솟값을 갱신시켜줍니다.

 

그리고 쿼리를 입력받습니다.

1이면 i번째 수를 v로 바꾸는 update,

2이면 i ~ j번째 수들 중 가장 작은 값을 출력하는 query를 실행시킵니다.

현재 구간[s, e]이 찾으려는 구간[l, r]의 밖에 있으면 INF를 리턴,

완전히 포함되어있으면 tree[node]를 리턴합니다.

 

 

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
49
50
51
52
53
54
55
56
#include <iostream>
#include <algorithm>
#define INF 2147483647
using namespace std;
 
int tree[400004];
int N, M;
 
int update(int node, int s, int e, int idx, int diff) {
    if (idx < s || idx > e) return tree[node];
    if (s == e) return tree[node] = diff;
 
    int m = (s + e) / 2;
    return tree[node] = min(update(node * 2, s, m, idx, diff), update(node * 2 + 1, m + 1, e, idx, diff));
}
 
int query(int node, int s, int e, int l, int r) {
    if (l <= s && e <= r) return tree[node];
    if (l > e || r < s) return INF;
 
    int m = (s + e) / 2;
    return min(query(node * 2, s, m, l, r), query(node * 2 + 1, m + 1, e, l, r));
}
 
void func() {
    int type, a, b;
    cin >> M;
    while (M--) {
        cin >> type >> a >> b;
        if (type == 1) {
            update(11, N, a, b);
        }
        else {
            cout << query(11, N, a, b) << '\n';
        }
    }
}
 
void input() {
    int x;
    cin >> N;
    for (int i = 1; i <= N; i++) {
        cin >> x;
        update(11, N, i, x);
    }
}
 
int main() {
    cin.tie(NULL); cout.tie(NULL);
    ios::sync_with_stdio(false);
 
    input();
    func();
 
    return 0;
}
cs

'algorithm > SegmentTree' 카테고리의 다른 글

boj 14719 빗물  (0) 2021.03.15
boj 2304 창고 다각형  (0) 2021.02.25
boj 13537 수열과 쿼리 1  (0) 2021.02.21
boj 6549 히스토그램에서 가장 큰 직사각형  (0) 2021.02.19
boj 2104 부분배열 고르기  (0) 2021.02.19

www.acmicpc.net/problem/13537

 

13537번: 수열과 쿼리 1

길이가 N인 수열 A1, A2, ..., AN이 주어진다. 이때, 다음 쿼리를 수행하는 프로그램을 작성하시오. i j k: Ai, Ai+1, ..., Aj로 이루어진 부분 수열 중에서 k보다 큰 원소의 개수를 출력한다.

www.acmicpc.net

i j k -> 배열의 i ~ j 번째 중에서 k보다 큰 수의 갯수를 출력하는 문제입니다.

저는 N개의 배열을 세그먼트트리에 저장해주고 각 구간에 포함되는 인덱스의 수를 벡터에 넣었습니다.

그리고 트리의 모든 범위를 한번씩 정렬해줍니다. (k보다 큰 수의 갯수를 찾기 위함입니다)

 

i j k 입력이 들어오면 query함수에서 찾아줍니다.

현재 들어와있는 구간[s, e]이 찾는 구간[l, r] 밖에 있으면 0을 리턴시켜주고,

완전히 포함되어있으면 tree[node]의 end - upper_bound를 리턴시켜줍니다.

 

end는 마지막원소 +1의 위치를 반환해주고,

upper_bound는 k 값을 초과하는 첫번째 숫자의 위치를 반환해줍니다.

따라서 k보다 큰 원소의 갯수를 구하려면 end - upper_bound를 해주시면 됩니다.

 

 

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
49
50
51
52
53
54
55
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
 
vector<int> tree[400004];
int N, M;
 
void update(int node, int s, int e, int idx, int diff) {
    if (s > idx || e < idx) return;
    tree[node].push_back(diff);
    if (s == e) return;
 
    int m = (s + e) / 2;
    update(node * 2, s, m, idx, diff);
    update(node * 2 + 1, m + 1, e, idx, diff);
}
 
int query(int node, int s, int e, int l, int r, int x) {
    if (s > r || e < l) return 0;
    if (l <= s && e <= r) return tree[node].end() - upper_bound(tree[node].begin(), tree[node].end(), x);
 
    int m = (s + e) / 2;
    return query(node * 2, s, m, l, r, x) + query(node * 2 + 1, m + 1, e, l, r, x);
}
 
void func() {
    int i, j, k;
    cin >> M;
    while (M--) {
        cin >> i >> j >> k;
        cout << query(11, N, i, j, k) << '\n';
    }
}
 
void input() {
    int x;
    cin >> N;
    for (int i = 1; i <= N; i++) {
        cin >> x;
        update(11, N, i, x);
    }
 
    for (int i = 1; i <= N * 4; i++) sort(tree[i].begin(), tree[i].end());
}
 
int main() {
    cin.tie(NULL); cout.tie(NULL);
    ios::sync_with_stdio(false);
 
    input();
    func();
 
    return 0;
}
cs

'algorithm > SegmentTree' 카테고리의 다른 글

boj 2304 창고 다각형  (0) 2021.02.25
boj 14438 수열과 쿼리 17  (0) 2021.02.21
boj 6549 히스토그램에서 가장 큰 직사각형  (0) 2021.02.19
boj 2104 부분배열 고르기  (0) 2021.02.19
boj 2243 사탕상자  (0) 2021.02.04

+ Recent posts