본문 바로가기

백준/Silver(1~5)

[백준]_1764번 : 듣보잡(파이썬 and C언어)

728x90
반응형
 

1764번: 듣보잡

첫째 줄에 듣도 못한 사람의 수 N, 보도 못한 사람의 수 M이 주어진다. 이어서 둘째 줄부터 N개의 줄에 걸쳐 듣도 못한 사람의 이름과, N+2째 줄부터 보도 못한 사람의 이름이 순서대로 주어진다.

www.acmicpc.net

특히 C언어로 짰을 때 얻을게 많았던 문제였다. 왜냐하면 파이썬에서는 정렬, 동일한 요소 인식 sort와 intersection으로 쉽게 얻을 수 있지만 C는 그런 기능을 스스로 만들어줘야 하기 때문에.. 따라서 다시 한번 파이썬에 감사하는 시간을 갖자.

이번 문제에서는 파이썬보다 C를 더 비중 있게 다루도록 하겠다. 


시도 1(Python)

import sys
input = sys.stdin.readline

nls = set()
mls = set()
N, M = map(int, input().split())
for _ in range(N): nls.add(input().strip())
for _ in range(M): mls.add(input().strip())
ans = list(nls.intersection(mls))
print(len(ans))
for el in sorted(ans): print(el)

<해석>

듣도 못한 사람을 담는 집합 nls, 보도 못한 사람을 담는 집합 mls를 만들어 준다 여기서 필자가 저질렀던 실수는 nls={ }와 같이 선언하고 nls가 집합처럼 행동하길 바랐던 것이다... 이름들을 모두 입력 받고 nls, mls사이에 존재하는 교집합을 ans에 담아주고 정답을 출력해 준다.


시도 2(C언어)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int compare(const void *a, const void *b) {
    return strcmp(a, b);
}

typedef struct {
    char user[21];
} name;

typedef struct {
    char ans[21];
} ans;

name nmarr[1000001];
ans arr[500001];

int main() {
    int N, M;
    scanf("%d %d", &N, &M);
    for (int i = 0; i < N + M; ++i) scanf("%s", nmarr[i].user);
    int add_index = 0;
    qsort(nmarr, N + M, sizeof(nmarr[0]), compare);
    for (int i = 0; i < N + M; ++i) {
        if (strcmp(nmarr[i].user, nmarr[i + 1].user) == 0) strcpy(arr[add_index++].ans, nmarr[i].user);
    }
    printf("%d\n", add_index);
    for (int i = 0; i < add_index; ++i) {
        printf("%s\n", arr[i].ans);
    }
    return 0;
}

<해석>

먼저 구조체를 사용해 자료의 저장을 보기 쉽게 설정해 준다. 모든 이름들을 하나의 배열 nmarr로 모두 입력받은 후 일단 사전순 정렬(qsort)을 먼저 거쳐준다. 여기서 들 수 있는 의문은 위의 파이썬에서는 듣도 못한 사람과 보도 못한 사람을 나누어서 비교했는데 여기서 qsort를 사용하면 다 섞이는 거 아닌가 생각할 수도 있다. 하지만 상관없다!! 왜냐하면 다음 반복문과 조건문 코드를 보면 알 수 있다. 섞인 상태에서도 중복되는 이름은 조건문으로 확인 가능하고 중복 이름들은 arr로 복사해 준다. 이때 add_index 하는 변수를 따로 선언해줘서 arr에 들어가는 이름들의 수를 세어준다. 그래야 중복 이름의 개수를 쉽게 알 수 있기 때문이다.   

728x90
반응형