https://www.acmicpc.net/problem/1517

 

예전에 재채점되어 틀린 문제를 다시 풀게 되었습니다.

 

덕분에 이 글은 내리게되었네요 ㅠ

이전에는 merge sort로 풀었던 문제라 그건 수정해서 AC를 받았고, 이번에는 다른 방법으로 접근했습니다.

 

이 문제처럼 버블 소트의 특징을 이해하고 있다면 해결할 수 있습니다.

버블소트는 앞뒤의 수를 비교하여 앞의 숫자가 크면 두 수의 위치를 swap 하게 됩니다.

이 문제는 그 swap의 횟수를 구하는 문제로 본인보다 앞에 있지만 더 큰수의 갯수를 세어주면 된다는 결론이 나옵니다.

 

그러면 입력으로 주어지는 정수들로 세그먼트 트리를 이용할 수 있습니다.

본인보다 먼저 트리에 들어간 수 중에 본인보다 큰 수의 갯수를 카운팅하도록 합니다.

하지만 입력의 범위는 절댓값이 10억이라서 배열로 표현하기는 어려울 수 있습니다.

그렇다면 N이 50만이라는 것을 이용하여 좌표압축 기법을 생각할 수 있습니다.

 

https://whyeskang.com/362

 

좌표 압축 (Coordinate Compression)

3년전에 대학 과제로 좌표 압축 기법을 활용하는 문제가 나왔었지만 이해를 못해서 풀지 못했습니다. 지금와서 보니 생각보다 간단했고, 정리하면서 포스팅합니다. 우선 좌표압축이란, 수의 범

whyeskang.com

위 게시글을 참고하시면 문제없이 좌표압축 기법을 사용하실 수 있을 것입니다.

 

좌표압축이 끝났다면 1 ~ N의 범위 내에서 본인보다 큰 수의 갯수를 세그먼트 트리를 활용하여 구할 수 있습니다.

입력이 들어온 순서대로 query 함수를 이용하여 갯수를 구하고, update를 시켜주면 차례대로 구할 수 있습니다.

 

 

[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
#include <iostream>
#include <algorithm>
#define MAX 500001
using namespace std;
typedef long long ll;
typedef pair<intint> pii;
 
pii list[MAX];
ll tree[MAX << 2];
int N;
 
void compress() {
    sort(list, list + N);
    int pre = 1e9 + 1;
    int cnt = 0;
    for (int i = 0; i < N; i++) {
        if (pre != list[i].first) cnt++;
        pre = list[i].first;
        list[i].first = cnt;
    }
    sort(list, list + N, [](pii a, pii b) {
        return a.second < b.second;
    });
}
 
ll update(int node, int l, int r, int x) {
    if (x < l || r < x) return tree[node];
    if (l == r) return ++tree[node];
 
    int m = (l + r) >> 1;
    return tree[node] = update(node << 1, l, m, x) + update((node << 1+ 1, m + 1, r, x);
}
 
ll query(int node, int l, int r, int s, int e) {
    if (s <= l && r <= e) return tree[node];
    if (l > e || s > r) return 0;
 
    int m = (l + r) >> 1;
    return query(node << 1, l, m, s, e) + query((node << 1+ 1, m + 1, r, s, e);
}
 
void func() {
    compress();
 
    ll ret = 0;
    for (int i = 0; i < N; i++) {
        ret += query(11, N, list[i].first + 1, N);
        update(11, N, list[i].first);
    }
    cout << ret << '\n';
}
 
void input() {
    cin >> N;
    for (int i = 0; i < N; i++) {
        cin >> list[i].first;
        list[i].second = i;
    }
}
 
int main() {
    cin.tie(NULL); cout.tie(NULL);
    ios::sync_with_stdio(false);
 
    input();
    func();
 
    return 0;
}
cs

 

Java로 문제를 풀다가 의문이 든게 있는데

 

Arrays.sort(array, from, to, comparator) 메소드와

Arrays.sort(array, comparator) 메소드의 성능 차이에 대해 궁금해졌습니다.

AC를 받은 코드는 Arrays.sort(array, from, to, comparator) 메소드를 사용한 코드고,

TLE를 받은 코드는 Arrays.sort(array, comparator) 메소드를 사용한 코드입니다.

그거 말고는 차이가 없는데 결과가 다르게 나오는 상황이라.. 당황했던 기억이 있습니다.

이걸 시스템상의 문제로 짚고 넘어가도 될만한 것인지는 잘 모르겠네요. 그냥 억까라고 해야하나 이걸

 

 

[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
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.Comparator;
import java.util.StringTokenizer;
 
public class Main {
    private static int list[][];
    private static long tree[];
    private static int N;
 
    private static void compress() {
        Arrays.sort(list, 0, N, (o1, o2) -> {
            if (o1[0== o2[0]) return o1[1- o2[1];
            return o1[0- o2[0];
        });
        int pre = Integer.MAX_VALUE;
        int cnt = 0;
        for (int i = 0; i < N; i++) {
            if (pre != list[i][0]) cnt++;
            pre = list[i][0];
            list[i][0= cnt;
        }
        Arrays.sort(list, 0, N, Comparator.comparingInt(o -> o[1]));
    }
 
    private static long update(int node, int l, int r, int x) {
        if (x < l || r < x) return tree[node];
        if (l == r) return ++tree[node];
 
        int m = (l + r) >> 1;
        return tree[node] = update(node << 1, l, m, x) + update((node << 1+ 1, m + 1, r, x);
    }
 
    private static long query(int node, int l, int r, int s, int e) {
        if (s <= l && r <= e) return tree[node];
        if (l > e || s > r) return 0L;
 
        int m = (l + r) >> 1;
        return query(node << 1, l, m, s, e) + query((node << 1+ 1, m + 1, r, s, e);
    }
 
    private static void func() {
        compress();
 
        long ret = 0;
        for (int i = 0; i < N; i++) {
            ret += query(11, N, list[i][0+ 1, N);
            update(11, N, list[i][0]);
        }
        System.out.println(ret);
    }
 
    private static void input() throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        list = new int[N][2];
        tree = new long[(N << 2+ 1];
        st = new StringTokenizer(br.readLine());
        for (int i = 0; i < N; i++) {
            list[i][0= Integer.parseInt(st.nextToken());
            list[i][1= i;
        }
    }
 
    public static void main(String[] args) throws Exception {
        input();
        func();
    }
}
cs

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

boj 4442 빌보의 생일  (0) 2024.08.01
boj 8330 순열  (0) 2024.07.21
boj 17131 여우가 정보섬에 올라온 이유  (3) 2024.04.25
boj 12895 화려한 마을  (0) 2022.09.07
boj 10167 금광  (0) 2022.09.02

23기 운영진 활동을 마무리하여 수료했고, 시니어 자격으로 첫 활동을 하게되었다.

물론 활동기간은 24년 1월 ~ 3월이었지만 회고 쓰기가 귀찮아서 미루다가 미루다가 미루다가 지금에서야 쓴다 ^^

 

모집

우선 시니어는 대체적으로 선착순으로 모집된다.

그래서 모집 신청이 열리기 5분전부터 대기해서 신청을 파바박 했던 기억이 난다.

직전 기수에 활동점수가 좋았고, 첫 시니어라서 비교적 쉽게 선발될 수 있었다.

내가 항상 넥스터즈 활동을 하면서 목표로 잡았던건 새로운 것들을 경험하기였다.

기술적인게 아니라도 상관없다. 무조건 새로운 것들을 접한다면 그것이 경험이 된다. 라는게 내 마인드다.

 

활동

우선 팀을 고를때는 주제에 대한 나의 관심도를 높게 봤던것 같다.

특정 기술에 대해 경험해보고 싶거나 내가 사용하고싶은 주제를 원했고, 그런 팀이 두팀 정도 있었다.

결과적으로는 1지망에 뽑은 팀에 선정되어 기분이 좋았다.

우선 PM님부터 기술에 욕심이 많아보였고, 발표때 컨벤션이나 코드리뷰를 언급하는걸로 봐서 진심인듯 보였다.

발표가 끝나자마자 질문도 생각하지 않고 가장 먼저 달려가서 어필만 했던 기억이 난다.

 

이번 활동에서 내가 기대했던 기술들은 web socket과 지도 api인데

지도는 FE분들이 다 맡아주셨기 때문에 생각보다 할일이 줄어서 여유롭겠다고 생각했다.

 

 

그러나 그건 오산이었다.

web socket은 우리 BE들이 처음 다뤄보는 기술이었기에 생각보다 오래걸렸고,

각종 버그들을 맞이하면서 최종발표 당일까지 개발하는 결말로 마무리되었다.

 

이 회의록들을 보니 정말.. 열심히 했구나 라는 생각이 들었다.

주 1회는 오프라인으로 전직군 팀원들이 모여서 회의를 했고, 직군별로 정규적인 온라인 회의를 하거나 급할때 긴급 회의를 하기도 했다.

 

처음에는 우리 FE 개발자들이 무서웠다.

git, jira 전략과 컨벤션, 어떤 기술을 사용할지, cicd는 어떤 방식으로 할지 이런것들을 빠른 시간내에 정리하는 것들을 보면서

우리도 뒤쳐지지 않기 위해 최대한 머리를 쥐어짜내며 회의를 했던 기억이 난다.

그리고 변경사항이 적은 pr에도 코멘트가 정말 많이 달리면서 자잘한것 하나하나마저 맞춰가려는 것과 이 프로젝트에 얼마나 진심인지를 알 수 있었다.

덕분에 자극을 받을 수 있었고, 원하는 목표까지 개발할 수 있었다고 생각한다.

 

여태 3번의 기수동안 2번의 넥나잇과 1번의 넥버닝에 참여했지만 이렇게 시간이 빨리갔던 넥나잇은 처음인것 같다.

web socket을 만만하게 봤던 탓인지 생각보다 남아있는 작업들이 많다는걸 느꼈다.

양도 양이지만 handler, interceptor, exception 등 해야할 것들이 정말 많았다.

개발했다가 삭제하고 근데 그걸 다시 살리고 다시 삭제하고.. 이런 일들이 많았던것 같다.

시간이 1주일밖에 남지 않았는데 BE-FE간 socket 연결조차 되지않았어서 해결하는데 시간을 갈아넣었던것 같다.

한참 작업을 하다가 주위를 둘러봤는데 다들.. 여유롭게 놀면서 하시는것 같더라 ㅎㅎㅎ 우리만 작업해..

근데 어떡하겠어.. 좀비마냥 축 늘어져서 기계처럼 작업을 일단 해야했기 때문에 다른생각 갖지 않고 작업만 했다. 아니지.. 다른생각을 가지지 못한거야

중간에 팀원분이 보드게임을 가져와주셔서 1시간정도 리프레쉬 시간을 가졌던건 다행이라고 생각한다. 덕분에 머리가 어떻게든 돌아갔던것 같다 ^^..

 

8주라는 시간동안 정말 개발을 열심히 많이 한것 같다.

시작부터 달렸는데 마지막에도 달리고있었다..

위에서 언급한것처럼 최종발표 당일 새벽에 게더에 모여서 작업을 했었고, 발표 직전까지도 수정하고 최종배포하고 정신이 없었다.

그래도 문제를 해결하고 최종발표를 무사히 마쳐서 다행이라고 생각했다.

 

이번 활동에서 web socket을 다루긴 했지만 부족함이 많다고 느낀다.

동시편집 기능에 메시지에 유용한 stomp를 사용한 것도 그중 한가지다.

시간이 부족하다보니 일단 몇 번 해봤던 기술들을 써서 구현을 하긴 했는데

이걸 stomp를 버리는 방향으로 수정한다거나 websocket 테스트코드를 추가하는 등 앞으로 해야할게 더 많아보인다.

그리고 지금 구현되어 있는것들이 정석적인 방법은 아니라고 생각해서 더 효율적인 방법이 있는지 찾아봐야 할 것이다.

아쉽게도 취준이 겹치고 다른 일들이 있어서 추가 디벨롭을 하지 못한건 아쉽지만 충분히 다뤄볼만한 것들이라 todolist에 정리해야 될것 같다.

 

마무리

매번 프로젝트하면서 느끼지만 만족스러웠던 적은 없었던것 같다.

그만큼 프로젝트에는 진심이었고, 더 잘할 수 있었다는 아쉬움에 그랬던것 같다.

생각보다 볼륨이 컸고, 새벽늦게까지 작업하는 팀원들이 진짜 너무 고생한것 같다.

그렇게 했는데도 최종발표 당일 새벽에 1시간씩 교대로 자면서 QA 봐주고 수정하고 했던건.. 기억에 계속 남을것 같다.

작업이 늦게 끝나서 세션 장소에 가서 시연 시나리오를 짜고 테스트해봤는데 또 에러를 발견해서 발표직전까지 수정했던건 정말 아찔했다.

다른분들도 우리들의 다급한 모습을 보면서 안쓰러움을 느끼시진 않으셨을까 생각해본다 ㅎ.. 그래도 열심히 했잖아 ^^!

 

이번에도 정말 좋은 팀원들을 만났다.

웹 프로젝트였고, BE2 FE2 DE2로 총 6명으로 구성되었다.

프론트엔드 개발자분들은 시작부터 전력질주를 하며 내 동기부여를 이끌어내주셨고,

디자이너분들은 프레이머를 이용해서 반응형 웹이나 발표자료들을 만드시는걸 보고 신기했다. 디자이너는 언제나 새롭고 신기한걸 하신다.

우리 백엔드는 둘다 프로젝트를 2개씩 하고있었는데 socket과 redis의 지옥에서 헤어나오기 위한 노력을 정말 많이 해주셨다.

대부분이 넥스터즈 외에 무언가를 하고 있었음에도 이정도의 결과가 나왔으니 만족하지만 추가개발은 무산된것 같아서 아쉽긴 하다.

 

내가 직전기수에 운영진이었어서 그런지 이번 운영진들은 어떻게 하는지 관심을 가졌던것 같다.

이번기수 운영진분들도 정말 열심히 준비하고 진행도 깔끔하게 잘한다는 것을 느꼈다.

기존에 진행하던 것들을 이어서 하기도, 새로운걸로 바꿔보기도 하면서 회원들의 니즈를 맞추려고 하는 것들이 보였다.

아 물론 우리가 인수인계를 잘해준 것도 어느정도 있었겠지만 ^^^^^^

 

무엇보다도 놀랐던건 6주차에 넥밋업 세션이 진행되어 내/외부에서 강연자분들을 초청하여 발표를 진행하고, 인사이트를 얻는 시간이 있다.

내가 했을 때와는 다르게 유명한분들도 섭외가 되고, 전체적으로 퀄리티가 확 높아진 것 같은 느낌이 들었다.

이 세션에서 나는 정말 많은 인사이트를 얻었고, 마인드에 변화를 가져가는 계기가 되었다.

나중에 운영진에게 물어보니 일단 시도해봤더니 그쪽에서 수락을 해주셨다고 한다..

이번 운영진분들도 끝까지 진행 잘해주셔서 고생 많으셨다고 말씀드리고싶다.

 

22기부터 쉬지않고 활동을 했지만 다음 기수는 쉬려고 한다.

작년까지만 해도 이거 하면서 취준하면 되지~ 라는 마인드였지만 막상 하니까 쉽지않다는 것을 느꼈다.

그래서 이번에는 온전히 취준에만 집중해보려는 생각으로 25기 신청은 하지 않았다.

지금까지의 생각은 재취업을 한 이후에 다시 활동할 생각이지만 사람이라는게 언제든지 바뀔 수 있으니 가능성은 열어두려고 한다.

 

Nexters 24기

AUDY 개발한 피컵부 팀

모두 고생 많으셨습니다!

'잡담' 카테고리의 다른 글

엘리스 코드 챌린지 예선 후기  (2) 2024.07.20
6월 회고  (0) 2024.07.01
5월 회고  (1) 2024.06.07
4월 회고  (2) 2024.05.13
3월 회고  (0) 2024.04.13

https://www.acmicpc.net/problem/3114

 

(1, 1)에서 출발하여 (N, M)에 도착했을 때 사과 + 바나나의 최대를 구하는 문제입니다.

이동은 아래, 오른쪽, 오른쪽 + 아래 만 가능합니다.

 

(x, y) 기준 사과 + 바나나의 합은

1. (x, y) ~ (x - 1, y) 까지는 바나나

2. (x + 1, y) ~ (N, y) 까지는 사과

두개를 더하여 계산합니다.

그렇다면 사과와 바나나의 누적합은 각각 구할 수 있고, 세로별로 누적합을 구하도록 합니다.

 

세팅이 완료되었다면 점화식을 구해봅니다.

이동 가능한 방향이 어떻게 되는지를 이용하면 (x, y) 기준 3개 중 하나를 답으로 가져갈 수 있습니다.

(x - 1, y - 1), (x, y - 1)에서 왔을 경우 y 좌표가 바꼈으므로 이전에 구했던 누적합을 더하면 됩니다.

(x - 1, y)에서 왔을 경우 y좌표가 바뀌지 않았으므로 누적합 범위를 조정해야 합니다.

 

dp 값을 채워나가는 도중에 dp[N][M]보다 커지는 경우가 있을 수 있으니 dp[N][M]를 명시하여 출력해주시면 되겠습니다.

 

 

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
#include <iostream>
#include <algorithm>
#define MAX 1501
using namespace std;
 
int sumA[MAX][MAX], sumB[MAX][MAX], dp[MAX][MAX];
int N, M;
 
void func() {
    for (int i = 1; i <= N; i++) {
        for (int j = 1; j <= M; j++) {
            if (j == 1) {
                dp[i][j] = sumA[N][j] - sumA[i][j];
                continue;
            }
 
            int tmp = sumA[N][j] - sumA[i][j] + sumB[i - 1][j];
            dp[i][j] = max(max(dp[i - 1][j - 1], dp[i][j - 1]) + tmp, dp[i - 1][j] - sumA[i][j] + sumA[i - 1][j]);
        }
    }
 
    cout << dp[N][M] << '\n';
}
 
void input() {
    char ch;
    int x;
    cin >> N >> M;
    for (int i = 1; i <= N; i++) {
        for (int j = 1; j <= M; j++) {
            cin >> ch >> x;
            if (ch == 'A') {
                sumA[i][j] = x;
            }
            else {
                sumB[i][j] = x;
            }
            sumA[i][j] += sumA[i - 1][j];
            sumB[i][j] += sumB[i - 1][j];
        }
    }
}
 
int main() {
    cin.tie(NULL); cout.tie(NULL);
    ios::sync_with_stdio(false);
 
    input();
    func();
 
    return 0;
}
cs

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

boj 2216 문자열과 점수  (0) 2024.06.28
boj 1354 무한 수열 2  (0) 2024.06.27
boj 11560 다항식 게임  (0) 2024.06.13
boj 28018 시간이 겹칠까?  (0) 2023.08.08
boj 12841 정보대 등산  (0) 2023.07.31

https://www.acmicpc.net/problem/11560

 

약 1년만에 dp 문제입니다. 그동안 게을러 빠졌었네요 ^^..

 

이 문제는 N, M의 범위가 작으므로 미리 모든 값을 구할 수 있습니다.

그 다음 입력받는대로 출력만 하면 되는 방식입니다.

 

우선 점화식은 N을 직접 늘려가면서 다항식을 구해보시면 충분히 나올 수 있습니다.

 

여기서 알 수 있는 점화식은

i번째 다항식의 j번 계수[i - 1번째 다항식]의 [j - i번째 계수] ~ [j번째 계수]까지의 합으로 구할 수 있습니다.

그렇다면 점화식은

dp[i][j] = dp[i - 1][j - i] + dp[i - 1][j - i + 1] + ... + dp[i - 1][j]

이렇게 될 것이고, 코드로 그대로 옮겨주시면 되겠습니다.

 

 

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 <algorithm>
#define MAX_N 21
#define MAX_M 211
using namespace std;
typedef long long ll;
 
ll dp[MAX_N][MAX_M];
int N, M;
 
void init() {
    dp[1][0= 1LL;
    dp[1][1= 1LL;
    for (int i = 2; i < MAX_N; i++) {
        for (int j = 0; j <= (i * (i + 1)) >> 1; j++) {
            for (int k = max(0, j - i); k <= j; k++) {
                dp[i][j] += dp[i - 1][k];
            }
        }
    }
}
 
void func() {
    cout << dp[N][M] << '\n';
}
 
void input() {
    cin >> N >> M;
}
 
int main() {
    cin.tie(NULL); cout.tie(NULL);
    ios::sync_with_stdio(false);
 
    init();
 
    int tc;
    cin >> tc;
    while (tc--) {
        input();
        func();
    }
 
    return 0;
}
cs

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

boj 1354 무한 수열 2  (0) 2024.06.27
boj 3114 사과와 바나나  (0) 2024.06.13
boj 28018 시간이 겹칠까?  (0) 2023.08.08
boj 12841 정보대 등산  (0) 2023.07.31
boj 25427 DKSH를 찾아라  (0) 2023.05.21

https://www.acmicpc.net/problem/3758

 

구현문제는 문제만 잘 읽고 이해한다면 어렵지 않게 해결할 수 있습니다.

물론 저는 읽고 이해하는게 어렵습니다 ^^

 

팀 순위를 정하는 방식은

각 문제들을 해결하면서 얻은 점수의 합이 되겠고,

최종 점수가 같으면 풀이를 제출한 횟수가 적은 팀이 우선
제출 횟수도 같으면 마지막 제출 시간이 더 빠른 팀이 우선순위를 높게 가져갑니다.

 

그렇다면 입력단계에서 구해야할건

먼저 점수의 합은 입력으로 들어온 각 팀마다 문제별 최고점수를 저장하면 구할 수 있고,

제출한 횟수는 팀이 입력되는 횟수를 카운팅하여 구할 수 있고,

마지막 제출 시간은 입력들의 인덱스를 갱신하기만 하면 구할 수 있습니다.

 

이제 위에서 구한 정보들로 순위를 정할 수 있습니다.

문제에서는 본인의 순위만 출력하면 되기 때문에 본인보다 순위가 높은 팀을 카운팅하면 구할 수 있습니다.

 

위에서 언급한 팀 순위를 정하는 방식을 이용하여 특정 팀이 본인보다 높은지 확인해주시면 되겠습니다.

 

 

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
#include <iostream>
#include <algorithm>
#include <cstring>
#define MAX 101
using namespace std;
 
int scores[MAX][MAX];
int tries[MAX];
int cnts[MAX];
int N, K, T, M;
 
int getScore(int team) {
    int ret = 0;
    for (auto score : scores[team]) {
        ret += score;
    }
    return ret;
}
 
bool isBetter(int team) {
    int x = getScore(T);
    int y = getScore(team);
    if (x == y) {
        if (cnts[T] == cnts[team]) return tries[T] > tries[team];
        return cnts[T] > cnts[team];
    }
    return x < y;
}
 
void func() {
    int ret = 0;
    for (int i = 1; i <= N; i++) {
        if (i == T) continue;
        ret += isBetter(i);
    }
    cout << ret + 1 << '\n';
}
 
void input() {
    int id, no, s;
    cin >> N >> K >> T >> M;
    for (int i = 1; i <= M; i++) {
        cin >> id >> no >> s;
        scores[id][no] = max(scores[id][no], s);
        cnts[id]++;
        tries[id] = i;
    }
}
 
void init() {
    for (int i = 1; i <= N; i++) {
        memset(scores[i], 0sizeof(scores[i]));
    }
    memset(cnts, 0sizeof(cnts));
    memset(tries, 0sizeof(tries));
}
 
int main() {
    cin.tie(NULL); cout.tie(NULL);
    ios::sync_with_stdio(false);
 
    int tc;
    cin >> tc;
    while (tc--) {
        input();
        func();
        init();
    }
 
    return 0;
}
cs

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

boj 1756 피자 굽기  (0) 2024.08.08
boj 17143 낚시왕  (0) 2021.04.23
boj 20207 달력  (0) 2021.04.22
boj 17144 미세먼지 안녕!  (0) 2021.04.14
boj 2564 경비원  (0) 2021.04.13

RealMySQL 2권 스터디

저번달에 시도한 진행 방식이 마음에 들었고, 같은 방식으로 계속 진행중이다.

상대적으로 딥한 내용을 학습하기 때문에 지루해질 수가 있겠지만 스터디원 모두가 함께 공부하는 모습을 보며 동기부여를 계속 받는 느낌이다.

지난번 방식과 비교한다면 스터디원들과 소통하는 시간이 많아졌고, 자연스럽게 분위기도 좋아졌다.

다음에 다른 스터디를 진행하게 된다면 이 방법을 시도해보자고 의견을 낼 수 있을 것 같다.

 

1일 1알고리즘

1024일 넘어서 뱃지 받음

 

마무리

취준 기간이라 이러면 안되지만 휴식을 많이 가졌던것 같다.

저번에는 밤낮 바꿔가면서 준비해보려고 했지만 오히려 단점이 많았던것 같다.

이제는 일찍 자는 습관을 찾았고, 일찍 일어나니 하루가 정말 길게 느껴진다는 생각이 들었다.

6월은 정신차리자 ^^

'잡담' 카테고리의 다른 글

6월 회고  (0) 2024.07.01
Nexters 24기 회고  (2) 2024.06.16
4월 회고  (2) 2024.05.13
3월 회고  (0) 2024.04.13
2월 회고  (4) 2024.03.07

 

https://www.acmicpc.net/problem/1377

 

정렬 문제처럼 보이지만 아이디어를 요구하는 애드혹 문제입니다.

이 문제는 버블 소트의 특징을 이해하고 있어야 풀 수 있습니다.

이해하고 있어도 문제를 해결하는데 필요한 아이디어를 얻기까지 꽤 오랜 시간이 걸렸습니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
bool changed = false;
for (int i=1; i<=N+1; i++) {
    changed = false;
    for (int j=1; j<=N-i; j++) {
        if (A[j] > A[j+1]) {
            changed = true;
            swap(A[j], A[j+1]);
        }
    }
    if (changed == false) {
        cout << i << '\n';
        break;
    }
}
cs

우선 문제에 작성되어있는 코드로 i가 어떻게 출력되는지 찾아야 합니다.

우선 위 코드는 앞에 위치한 수가 자신보다 크다면 두 수의 위치를 변경하는 방식으로 구현된 정렬입니다.

이 로직에 의하면 범위 내 상대적으로 큰 수는 뒤쪽으로 이동하고, 상대적으로 작은 수는 앞쪽으로 이동하게 됩니다.

 

여기서 잡을 수 있는건 뒤쪽으로는 무한정 이동이 가능하지만 앞쪽으로는 한 칸만 이동이 가능하다는 것입니다.

즉 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
#include <iostream>
#include <algorithm>
#define MAX 500001
using namespace std;
typedef pair<intint> pii;
 
pii list[MAX];
int N;
 
void func() {
    sort(list, list + N);
 
    int ret = 0;
    for (int i = 0; i < N; i++) {
        ret = max(ret, list[i].second - i);
    }
 
    cout << ret + 1 << '\n';
}
 
void input() {
    cin >> N;
    for (int i = 0; i < N; i++) {
        cin >> list[i].first;
        list[i].second = i;
    }
}
 
int main() {
    cin.tie(NULL); cout.tie(NULL);
    ios::sync_with_stdio(false);
 
    input();
    func();
 
    return 0;
}
cs

'algorithm > ad-hoc' 카테고리의 다른 글

boj 5527 전구 장식  (0) 2024.07.30
boj 14864 줄서기  (0) 2024.07.26
boj 2381 최대 거리  (0) 2024.07.25
boj 14675 단절점과 단절선  (0) 2024.07.23
boj 27468 2배 또는 0.5배  (0) 2024.07.22

RealMySQL 2권 스터디

내용이 많이 딥해져서인지 스터디원들의 동기부여가 많이 떨어진것 같은 느낌이 들었다.

스터디장 주도하에 회의를 했고, 방식을 바꿔보기로 했다.

기존 방식으로는 책 내용을 정리하고 발표하는 방식이었다면 이제는 같이 책을 읽어보자! 라고 했고, 바로 시도해봤다.

모각코 방식으로 생각보다 집중이 잘된다는 느낌이 들었고, 괜찮은 방법인것 같다.

 

1일 1알고리즘

 

마무리

취준은 하고 면접도 보고는 있는데 CS가 많이 부족하다는 생각이 들었다.

물론 내가 공부한건 절대 안나오기 때문에 다 공부하면 다 안나오지 않을까 생각해본다 ^^

회고 하나가 더 남았는데 귀찮은데.. 조금씩 써봐야지

'잡담' 카테고리의 다른 글

Nexters 24기 회고  (2) 2024.06.16
5월 회고  (1) 2024.06.07
3월 회고  (0) 2024.04.13
2월 회고  (4) 2024.03.07
1월 회고  (0) 2024.02.15

https://www.acmicpc.net/problem/17131

 

17131번: 여우가 정보섬에 올라온 이유

첫 줄에 별의 개수 N이 주어진다. 그 다음 줄부터 N개의 줄에 걸쳐 별의 좌표 x y가 주어진다.

www.acmicpc.net

알고리즘 정말 오랜만이네요.

 

만들어야 하는 별자리는 V 모양이며, V를 회전한 모양은 포함하지 않습니다. (ex. < > ^ ㄱ ㄴ 모양은 X)

여기서 가로를 x, 세로를 y 축이라고 가정했을 때

예시 기준 a, b, c만 별자리로 인정할 수 있습니다.

 

그리고 문제에서도 a.x < b.x < c.x이고 a.y > b.y < c.y 라고 친절히 설명도 해줍니다.

이 조건에서 라인 스위핑 기법을 활용하기 위해 y 값 기준 내림차순 정렬이 필요하다는 것을 알 수 있습니다.

그러면 같은 y값들을 가지고 먼저 놓여진 별들x 값이 작은 별들의 갯수와 x 값이 큰 별들의 갯수를 곱하면 별자리의 갯수를 구할 수 있습니다.

어떤 정해진 범위 내에서 특정 범위의 값을 구한다고 했을때 구간합을 떠올릴 수 있습니다.

구간합을 구하는 알고리즘은 세그먼트 트리가 있습니다.

그러면 이 문제는 세그먼트 트리 + 라인 스위핑을 활용하여 해결할 수 있습니다.

 

로직의 순서는

1. 위에서 설명한것처럼 y 좌표 기준으로 내림차순 정렬합니다.

2. 같은 y값을 가진 별들을 가지고 x 값이 작은/큰 별들의 갯수를 구합니다.

3. 그 다음 같은 y값을 가진 별들을 한꺼번에 트리에 업데이트를 합니다.

 

이게 끝이지만 주의할점은

같은 y값을 가진 모든 별들이 2번 과정이 끝난 후에 3번 과정을 같이 진행해야합니다.

이 풀이의 핵심은 2번 과정에 들어왔을때 트리에 있는 값들은 모두 자신보다 y 값이 큰 별 이라는 것입니다.

그래서 저는 같은 y값을 가진 별들을 벡터에 넣어주고, 3번 과정에서 한꺼번에 업데이트를 했습니다.

 

 

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
#include <iostream>
#include <algorithm>
#include <vector>
#define MAX 200001
#define MOD 1000000007
using namespace std;
typedef long long ll;
typedef pair<intint> pii;
 
ll tree[MAX << 3];
pii list[MAX];
int N;
 
bool cmp(pii a, pii b) {
    if (a.second == b.second) return a.first < b.first;
    return a.second > b.second;
}
 
ll update(int node, int l, int r, int idx) {
    if (idx < l || r < idx) return tree[node];
    if (l == r) {
        return tree[node] = tree[node] + 1;
    }
 
    int m = (l + r) >> 1;
    return tree[node] = update(node << 1, l, m, idx) + update((node << 1+ 1, m + 1, r, idx);
}
 
ll query(int node, int l, int r, int s, int e) {
    if (s <= l && r <= e) return tree[node];
    if (e < l || r < s) return 0LL;
 
    int m = (l + r) >> 1;
    return query(node << 1, l, m, s, e) + query((node << 1+ 1, m + 1, r, s, e);
}
 
void func() {
    sort(list + 1, list + 1 + N, cmp);
 
    ll ret = 0;
    int pre = list[1].second;
    vector<int> v;
    for (int i = 1; i <= N; i++) {
        int m = list[i].first;
        if (pre == list[i].second) {
            v.push_back(m);
        }
        else {
            for (auto x : v) {
                update(10, (MAX - 1<< 1, x);
            }
            v.clear();
            pre = list[i].second;
            v.push_back(m);
        }
        ret = (ret + query(10, (MAX - 1<< 10, m - 1* query(10, (MAX - 1<< 1, m + 1, (MAX - 1<< 1)) % MOD;
    }
 
    cout << ret << '\n';
}
 
void input() {
    cin >> N;
    for (int i = 1; i <= N; i++) {
        cin >> list[i].first >> list[i].second;
        list[i].first += (MAX - 1);
    }
}
 
int main() {
    cin.tie(NULL); cout.tie(NULL);
    ios::sync_with_stdio(false);
 
    input();
    func();
 
    return 0;
}
cs

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

boj 8330 순열  (0) 2024.07.21
boj 1517 버블 소트  (0) 2024.06.16
boj 12895 화려한 마을  (0) 2022.09.07
boj 10167 금광  (0) 2022.09.02
boj 16993 연속합과 쿼리  (0) 2022.08.29

넥스터즈 8주차

2월에 설 연휴가 있어서 3월까지 진행되었다.

생각보다 개발 시간이 오래걸려서 발표 당일 오전까지 개발을 했고, 사실상 밤을 새고 세션에 참여했다.

다행히도 핵심 기능들은 모두 완료해서 라이브 시연도 문제없이 끝났고, 24기 활동이 마무리되었다.

이후에 추가 구현이나 개선작업은 추가 회의를 통해 진행할 예정이다.

 

RealMySQL 2권 스터디

1년이상 이어진 스터디는 들어본적 없다.

1권을 끝내고 1~2달 정도 휴식 및 재정비 시간을 가지긴 했지만 모든 스터디원들이 같이 2권을 시작했고, 끝이 보인다.

가끔 흥미가 떨어지는 등 진행이 주춤할 때도 있었지만 다들 책임감을 가지고 완주를 목표로 이어 나가고 있다.

 

1일 1알고리즘

와 좀만 더있으면 1000일이네

 

마무리

이력서도 끝났고, 공채는 올라오고 있지만 아직 좋은 소식은 없다.

사실 넥스터즈 24기가 끝나자마자 번아웃이 크게 찾아왔다.

난 왜이렇게 번아웃이 자주 찾아오는지, 아니면 내가 그렇게 생각하는건지? 그냥 모르겠다.

백수 생활이 오래돼서 그런가

모르겠고 공부나 하자

열심히 사는분들 진짜 리스펙합니다.

'잡담' 카테고리의 다른 글

5월 회고  (1) 2024.06.07
4월 회고  (2) 2024.05.13
2월 회고  (4) 2024.03.07
1월 회고  (0) 2024.02.15
12월 회고  (6) 2024.01.09

넥스터즈 5~ 7주차

5주차 중간발표 시간에 다른 팀의 진행 상황을 확인했다.

다들 생각보다 빠르게 출시가 되는 팀도 있었고, 갈길이 멀어보이는 팀도 있었다. 우리 얘기다.

 

web socket을 만만하게 보고 여유를 가졌다가 넥나잇 세션때 정말 많은 작업을 했다.

22기에 넥버닝, 23기에 넥나잇 세션을 경험했지만 시간이 이렇게 빨리 간건 처음인것 같다.

예전에는 놀기도 하고 돌아다니고 그랬었는데.. 팀원들 모두 작업만 하다가 벌써 아침이야? 했던 기억이 난다.

새벽에 잠오는거? 그럴 시간이 없었다 그냥 작업했다..

 

이 글을 쓰는 현재는 무사히 마무리가 되었지만 리펙토링 & 개선 작업은 무조건 진행할 예정이다.

하자고 말을 한건 아니었지만 프로젝트 초기부터 이후 개발을 생각했기에 다들 참여하는 분위기다.

 

RealMySQL 2권 스터디

RealMySQL 스터디를 작년 3월에 시작했는데 벌써 1년이라는 시간이 지났다.

1권을 마치고 2권의 핵심적인 부분까지 마무리가 되었고, 추가로 뒤에 나오는 부분까지 훑고 지나가는게 좋을 것 같아서 계속 진행중이다.

스터디원분들이 많이 바쁘시지만 끝까지 참여하시는게 대단하다고 생각이 든다.

이렇게 오래가는 스터디도 별로 없다던데 ㅎㅎ

 

1일 1알고리즘

 

마무리

벌써 공채가 열렸네? 일어나 일해야지 ^^^^^^^^^

'잡담' 카테고리의 다른 글

4월 회고  (2) 2024.05.13
3월 회고  (0) 2024.04.13
1월 회고  (0) 2024.02.15
12월 회고  (6) 2024.01.09
11월 회고  (2) 2023.12.12

SPURT 프로젝트 개선

약간의 수정과 리펙토링 진행했다.

이번달 까지는 정기적으로 모여서 회의도 하고 그랬지만

다음달부터는 일정상 개인적으로 천천히 진행할 예정

 

넥스터즈 1 ~ 4주차

넥스터즈 24기 정규활동이 시작되었다.

이전 기수 경험 덕분인지 세션 일정이나 운영 부분에서 운영진들이 얼마나 고생하는지 바로 알것 같다.

아 물론 우리가 앞에서 잘했으니 ㅎㅎㅎㅎ 이번 기수도 영향을 받은게 아닌가~

 

이번 기수에도 새로운 경험을 원했고, PM분들의 발표를 듣자마자 딱 여기다싶은 팀이 있었다.

PM과의 대화 시간에도 먼저 가서 어필을 했고, 팀원으로 뽑히게 되었다.

 

우리 팀원들은.. 상당히 잠이 없으신 분들인것 같다.

새벽 늦게까지도 작업을 정말 많이 하시고 열심히 하시는 분들만 모인것 같다.

너무 열심히 하셔서 괜히 눈치가 보이는? 그런 표지션이 된것 같은데 열심히 해야지 ^^^^

 

프로젝트를 두개씩 하다보니 진행상황이 생각보다는 늦어진것 같지만

프론트엔드 업무가 상당히 많기에.. 뒤쳐지지는 않은 것 같아서 다행이라는 생각이 든다.

이제 프로젝트 하나가 끝났기에 더욱 집중할 수 있을것 같다.

벌써 절반의 세션이 지났는데 최종발표까지는 프로젝트를 완주할 수 있도록 해야겠다.

 

RealMySQL 2권 스터디

1권으로 스터디를 시작해서 거의 10개월째 달려오고 있다.

이렇게 꾸준하게 스터디가 진행된다는것 자체가 스터디원들도 신기해하는것 같다.

그만큼 다들 책임감이 있기에 스터디가 유지되는게 아닌가 싶다.

2권 스터디도 약 1 ~ 2달 정도가 남았는데 잘 마무리되었으면 좋겠다.

 

1일 1알고리즘

 

마무리

이번 겨울은 뭔가 추운날이 적었던 느낌?

분명 저번 2월에는 디게 추웠던 기억이 나는데 요즘은 10도가 넘어가는 날이 많고 그냥 이상한것 같다.

아무튼.. aws에서 보안문제가 터져서 계속 해결하고 있는데 이것 또한 경험이라고 생각한다.

패스워드도 변경하고 MFA 설정까지 했고, 문제에 대해 후속처리를 진행중이다.

aws에서 연락이 온다면 바로 관심갖고 해결하자는 교훈을 얻고간다 ^^

1월부터 이력서를 갈아엎자! 라고 목표를 세웠는데 아직까지 완성하지 못한 나에게 약간의 질책을 하면서 이력서나 써야지

다음 회고는 일찍 적도록 하자 ^^!

'잡담' 카테고리의 다른 글

3월 회고  (0) 2024.04.13
2월 회고  (4) 2024.03.07
12월 회고  (6) 2024.01.09
11월 회고  (2) 2023.12.12
10월 회고  (2) 2023.11.11

+ Recent posts