티스토리 뷰
[Codeforces 1070H] BerOS File Suggestion - 1600
문제 설명 :
처음에 n개의 파일이름(문자열)이 주어진다. 그 다음 q개의 쿼리가 들어오는데, 각 쿼리는 substring을 제시하여 n개의 파일 중에서 해당 substring 포함하는 파일은 총 몇 개인지와 존재한다면 아무 파일이름을 출력하면 된다.
풀이 :
정말 고민을 많이 했던 문제이다. 일단 n이 1만, q가 5만이기 때문에 각 쿼리마다 모든 n을 살펴보는 것은 시간이 초과된다( O(n*q) ). 따라서 반드시 전처리과정을 거친 뒤에야 쿼리를 받을 때 빠르게 답을 출력하는 형태가 될 것이라고 짐작했다. 실제로 솔루션은 한 문자열에서 나올 수 있는 모든 substring의 경우의 수를 map에다 저장해서 카운트 해놓고, 나중에 쿼리가 들어올 때마다 map에 저장된 값을 출력하면 되는 것이다. 이 풀이가 가능한 이유는 파일이름(문자열)의 최대 길이가 8글자이기 때문이다. 따라서 한 문자열에서 나올 수 있는 substring에 최대 경우의 수는 (1+2+3..+8)=28가지이다. n은 1만이므로 28만개의 공간이 사용되는 것이다.
주의할 점 :
한 문자열 내에서 동일한 substring이 여러번 등장할 수 있으므로(ex. aabaa) 일단 set에 substring을 넣어 중복을 제거한 뒤에 map에 넣어야지 중복 카운트를 피할 수 있다.
배운 점 :
string객체위 함수에 concat의 기능을 수행하는 push_back연산이 있다는 것을 깨달았다.
코드 :
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 79 80 81 82 83 | #include<stdio.h> #include<math.h> #include<string.h> #include<iostream> #include<functional> #include<string> #include<algorithm> #include<vector> #include<map> #include<set> #include<queue> #include<stdlib.h> #include<stack> using namespace std; /****************************Contest Template******************************/ typedef pair<int,int> pii; typedef pair<long long,long long> pll; typedef pair<int,int> Cord; typedef long long ll; typedef unsigned long long ull; // #define IMP // #define INF // const int MOD= struct S{ int a,b; S(){} S(int _a,int _b){ a=_a; b=_b; } const bool operator<(const S &o) const{ return a<o.a; } }; priority_queue<int,vector<int>,greater<int>> mpq; /****************************Contest Template******************************/ // const int SIZE= map<string,string> mss; map<string,int> msi; int main(){ int n,q; scanf("%d",&n); while(n--){ string str; cin>>str; set <string> ss; for(int i=0 ; i<str.size() ; i++){ string substr; for(int j=i ; j<str.size() ; j++){ substr.push_back(str[j]); ss.insert(substr); } } for(auto here:ss){ msi[here]++; mss[here]=str; } } scanf("%d",&q); while(q--){ string find; cin>>find; if(msi[find]!=0){ printf("%d ",msi[find]); cout<<mss[find]<<'\n'; } else{ printf("0 -\n"); } } return 0; } | cs |
'Problem Solving > String' 카테고리의 다른 글
[CF 828C] String Reconstruction (0) | 2019.07.23 |
---|---|
[Codeforces 1025C] Plasticine zebra (0) | 2019.05.03 |
[Codeforces 1138D] Camp Schedule (0) | 2019.03.29 |
1787-문자열의 주기 예측 (0) | 2018.12.03 |
4354-문자열 제곱 (0) | 2018.12.03 |