Algorithm/baekjoon
[BOJ 5052] 전화번호 목록
식빵민
2022. 7. 27. 18:47
5052번: 전화번호 목록
첫째 줄에 테스트 케이스의 개수 t가 주어진다. (1 ≤ t ≤ 50) 각 테스트 케이스의 첫째 줄에는 전화번호의 수 n이 주어진다. (1 ≤ n ≤ 10000) 다음 n개의 줄에는 목록에 포함되어 있는 전화번호가
www.acmicpc.net
문제 분석
- 시간 제한 : 1초
- 다뤄야 하는 전화번호의 개수 : 10,000
- 테스트 케이스 : 50
- 어떤 값이 다른 값의 substring인지를 파악하는 문제
풀이 방식
- 문자열로 입력받은 전화번호를 사전순으로 정렬 ⇒ (1,2,3...,999,1000)X, (1,10,100,1000,11,111,112...)O
- 첫번째부터 다음꺼랑 비교
- 어떤 값이 다른 값의 substring이라면 두 값은 붙어있을 수 밖에 없다.
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int t,n;
string num;
bool possible;
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cin>>t;
while(t--){
cin>>n;
possible = true;
vector<string>pb;
//clear시간을 줄이기 위해 테스트 케이스 안에서 벡터선언(PhoneBook)
while(n--){
cin>>num;
pb.push_back(num);//벡터에 입력
}
sort(pb.begin(), pb.end());//사전순으로 정렬
for(int i=1;i<pb.size();i++){
if(pb[i-1]==pb[i].substr(0,pb[i-1].size())){//substr이 발견되면
cout<<"NO"<<"\n";//NO 출력하고
possible = false;
break;//반복문 정지
}
}
if(possible) cout<<"YES"<<"\n";
//NO 출력한적 없으면 substr 발견된적 없는 것
}
return 0;
}
느낀 점
- 처음에는 <map>을 사용하면 풀 수 있을 거란 생각에 key를 어떤값으로 할까 이런 고민을 했다.
- 도저히 떠오르지 않아 다른 방법이 없을 까 하는 생각을 했고, 사전순으로 정렬되어 있으면 문제해결이 쉬어지겠다는 생각을 했다.
사전순으로 정렬하면 된다는 생각이 문제를 해결하는데에 결정적이었고, 이런 생각을 해내 뿌듯했다. - 문제를 풀고나서 <priority_queue>와 같이 저장할때 부터 저장하는 게 효율적일 수 도 있겠다는 생각이 들었으나 좀더 고민해보니, 새로운 값을 push할때나 맨앞의 값을 pop할때나 그때 그때 정렬해줘야 한다는 생각에 <vector>를 쓴 방법이 효과적이었겠다는 생각이 들었다.
시간복잡도 (1 테스트 케이스 기준)
- while문 n번 반복 ⇒ O(n)
- 사전순 정렬 ⇒ O(nlogn) 기대
- for문 벡터 크기 만큼 반복 ⇒ O(n)
- 비교 연산 ⇒ O(1)
☞ O(nlogn)