백준 1764 - 듣보잡
문제링크
문제 접근
- 순차탐색(sequential search)은 가장 간단하고 직접적인 탐색 방법이지만 데이터양이 많아질수록 비효율적이다. 이번 문제에서도 순차탐색의 경우 시간초과에 걸린다.
- 정렬된 배열에서 탐색할 수 있다면 이진탐색(binary search)이 가장 효과적이다. 이진탐색은 배열의 중앙에 있는 값을 조사하여 찾고자 하는 항목이 왼쪽 또는 오른쪽 부분 배열에 있는지를 알아내어 탐색의 범위를 반으로 줄인다. 이렇게 매 단계에서 검색해야 할 리스트의 범위를 반으로 줄인다.
의사코드(pseudo-code)
# define function
bool cmp(const string& str1, const string& str2)
- return str1 < str2
# main
- cin >> n >> m
- vector<string> no_hear(n)
- len = n<m ? n : m
- idx = 0
- vector<string> result(len)
- for i=0 to n-1:
- cin >> no_hear[i]
- sort(no_hear.begin(), no_hear.end(), cmp)
- for i=0 to m-1:
- cin >> str
- if binary_search(no_hear.begin(), no_hear.end(), str) is true:
- result[idx++] = str
- sort(result.begin(), result.begin()+idx, cmp)
- cout << idx
- for i=0 to idx-1:
- cout << result[i]
소스코드 및 분석
전체 코드
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
bool cmp(const std::string& str1, const std::string& str2) {
return str1 < str2;
}
int main()
{
int n, m;
std::cin >> n >> m;
std::vector<std::string> no_hear(n);
int len = n < m ? n : m;
int idx = 0;
std::vector<std::string> result(len);
for (int i = 0; i < n; i++)
std::cin >> no_hear[i];
std::sort(no_hear.begin(), no_hear.end(), cmp);
for (int i = 0; i < m; i++) {
std::string str;
std::cin >> str;
if (std::binary_search(no_hear.begin(), no_hear.end(), str))
result[idx++] = str;
}
std::sort(result.begin(), result.begin() + idx, cmp);
printf("%d\n", idx);
for (int i = 0; i < idx; i++)
std::cout << result[i] << "\n";
}
- algorithm 헤더파일에 있는 binary_search 함수를 이용했다. 이진탐색을 진행하기 전에 배열은 반드시 “정렬”되어 있어야함에 주의하자.
- 벡터컨테이너를 선언할 때 size 를 미리 설정해두어 일반 배열처럼 데이터를 삽입, 삭제 할 수 있도록 했다. 따라서, 경우에 따라 메모리를 확장해야하는 과정이 불필요하여 시간을 아낄 수 있다.
다른 풀이
- 시간복잡도를 O(n)으로 줄여야 제한 시간 안에 통과할 수 있을 것이라 생각했다. (sort 함수를 호출했으니 O(nlogn)) 정도의 시간 복잡도 일 것이다.
- 듣도 못한 사람 중에서는 중복된 이름이 없고, 보도 못한 사람 중에서도 중복된 이름이 없으니 두 부류에 모두 속한 사람만이 전체 명단에서 2번 존재하게 된다.
- 전체명단을 입력 받아 오름차순 정렬한 뒤 같은 이름이 연속으로 나열된 사람이 듣도 보도 못한 사람이 된다.
#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
using namespace std;
bool cmp(const string& s1, const string& s2) {
return s1 < s2;
}
int main()
{
cin.tie(NULL);
ios_base::sync_with_stdio(false);
int n, m;
cin >> n >> m;
int total = n + m;
vector<string> all_people;
for (int line = 0; line < total; line++) {
string str;
cin >> str;
all_people.push_back(str);
}
sort(all_people.begin(), all_people.end(), cmp);
vector<string> ans;
for (int i = 0; i < total - 1; i++) {
if (all_people[i] == all_people[i + 1])
ans.push_back(all_people[i++]);
}
cout << ans.size() << endl;
for (auto ele : ans)
cout << ele << endl;
}
Leave a comment