article thumbnail image
Published 2021. 7. 19. 00:33

결과

제주도 스쿠버 일정과 scpc일정과 겹쳐서 4시간 정도밖에 풀지 못했다. 2번까지 풀고 뒷 문제들이 크게 어려워 보이지 않았는데 다음 일정 때문에 못 풀어서 너무 아쉬웠다.

1. 친구들

N명의 사람이 있고, 각 사람은 d를 가지고 있는데 i번째 사람은 i + Di와 친구이다. i + Di > N이면 무시한다.

A와 B가 친구라면 B와 A도 친구다.

union find를 집합의 개수를 세면 풀 수 있다. 매우 쉬웠고 10분 정도만에 풀 수 있었다.

#include <iostream>
#include <cstring>

using namespace std;

int Answer;
int par[100005], lev[100005];

int find(int x) {
    if (x == par[x]) return x;
    return par[x] = find(par[x]);
}

void merge(int x, int y) {
    int a = find(x), b = find(y);
    if (a == b) return;
    if (lev[a] > lev[b]) swap(a, b);
    par[a] = b;
    lev[b] += lev[a];
    lev[a] = 0;
}

int main(int argc, char** argv)
{
	int T, test_case;

	cin >> T;
	for(test_case = 0; test_case  < T; test_case++)
	{
		Answer = 0;
        int N; cin >> N;
        for (int i = 1; i <= N; i++) {
            par[i] = i;
            lev[i] = 1;
        }

        for (int i = 1; i <= N; i++) {
            int ipt; cin >> ipt;
            if (i + ipt <= N) merge(i, i + ipt);
        }

        for (int i = 1; i <= N; i++) {
            if (lev[i]) Answer++;
        }
		cout << "Case #" << test_case+1 << endl;
		cout << Answer << endl;
	}
}

2. 이진수

길이가 n인 이진수 A가 주어주고 정수 t가 주어지고 아래 규칙으로 새로운 이진수 B를 만든다.

1. 만약 i>t이고, ait = 1이면 bi = 1이다.

2. 그렇지 않고 i nt이고, ai+t=1이면 bi=1이다.

3. else bi=0이다.

B t가 주어졌을 때, A를 복원해야 한다.

가능한 A가 여러 가지라면, 그중 가장 작은 것을 출력한다.

bi가 0이라면 bi-t, bi+t는 항상 0 이여야 하고, i <= t일 경우에 bi가 1이라면 ai+t는 1이고, bi가 0이라면 ai+t는 0이다. i + t > n인 경우는 bi가 1이라면 ai-t는 1이고, bi가 0이라면 ai-t는 0이다. 이것을 전처리해두고 나머지는 항상 더 작은 것으로 고르면 된다.

이 문제도 풀이는 금방 생각났지만 구현에서 약간 버벅거려서 시간을 조금 날렸다. 그리고 왜 그런진 모르겠는데 endl대신 "\n"을 사용했더니 계속해서 틀려서 endl으로 바꿨더니 맞았다.

#include <iostream>

using namespace std;

int arr[500005], ans[500005];
int flag[500005];

int main(int argc, char** argv)
{
	int T, test_case;

	cin >> T;
	for(test_case = 0; test_case  < T; test_case++)
	{
        int n, t; cin >> n >> t;
        for (int i = 1; i <= n; i++) {
            scanf("%1d", &arr[i]);
            flag[i] = 0;
            ans[i] = 0;
        }

        for (int i = 1; i <= n; i++) {
            if (i - t < 1 && i + t <= n) flag[i + t] = (arr[i] ? 1 : -1);
            if (i + t > n && i - t > 0) flag[i - t] = (arr[i] ? 1 : -1);
            else { 
                if (!arr[i] && i + t <= n && i - t > 0) flag[i + t] = flag[i - t] = -1; 
            }
        }

        for (int i = 1; i <= n; i++) if (flag[i] == 1) {
            ans[i] = 1;
        } 

        for (int i = t + 1; i <= n - t; i++) if (arr[i]) {
            if (i + t <= n && ans[i + t]) continue; 
            if (i - t <= n && ans[i - t]) continue; 
            if (i + t <= n && flag[i + t] == -1) ans[i - t] = 1;
            if (i - t > 0 && flag[i - t] == -1) ans[i + t] = 1;
            if (i + t <= n && i - t > 0 && flag[i + t] != -1 && flag[i - t] != -1) ans[i + t] = 1;
        }
        
		cout << "Case #" << test_case+1 << endl;
        for (int i = 1; i <= n; i++) cout << ans[i];
        cout << endl;
	}
}

_________________________________________________수정_________________________________________________

2솔이여서 1차에서 당연히 떨어졌을 줄 알았는데 통과했다.

'후기' 카테고리의 다른 글

2022 모비스 대회 후기  (0) 2022.07.05
원티드 쇼미더코드 후기  (0) 2022.04.15
2022 구글 코드잼 Qualification Round 후기  (0) 2022.04.03
구글 푸바 챌린지 후기  (0) 2022.03.16
2021 SCPC Round 2 후기  (0) 2021.08.07
복사했습니다!