티스토리 뷰
[CF 828C] String Reconstruction - 1700
문제 설명 :
n개의 부분문자열(substring)과 이 부분문자열이 전체 문자열에서 등장하는 시작 위치가 주어진다. 이 부분문자열의 정보를 바탕으로 전체 문자열을 구성할 때, 사전순으로 가장 앞서도록 만드는 문제이다. (입력되는 정보는 모순되지 않는다)
풀이 :
입력되는 정보는 모순되지 않으므로 단순하게 substring을 i번째 위치에 넣는다고 생각하면 된다. 하지만 naive하게 생각해서 k_i개의 위치에 대해서 substring의 모든 글자를 다 비교해보면 시간초과가 난다. 예를 들어 substring이 "aaa...aa"로 총 100만 글자이고, k_i=100만개 : {1,2,3,...100만}이라면 시간복잡도는 100만 * 100만이므로 터지게 된다. 따라서 이미 채워진 칸은 다음에 볼 때 제외시켜서 시간을 절약시켜야 한다. 이를 구현하기 위해서 set을 사용할 것이다. set에는 사용되지 않은 칸을 저장해 둘 것이다. 그래서 처음에 set에 1~200만을 집어넣는다. 그리고 substring의 위치가 제시되면, 그 위치의 lower_bound를 찾아서 글자수의 길이만큼 채우면 된다.
주의할 점 :
-
배울 점 :
set이나 map에서 lower_bound나 upper_bound를 찾을 때는 set.lower_bound(x) 로 사용하면 된다. 나는 처음에 lower_bound(set.begin(),set.end(),x)를 사용했는데 이 방식은 search하는데 O(N)만큼 걸린다고 한다.
그리고 set의 원소를 지우는 연산은 erase가 있으며 인자로 원소나 원소의 이터레이터를 넣어주면 된다. 반환 값은 지운 원소의 다음 원소의 이터레이터이다.
코드 :
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 | #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<assert.h> #include<stdlib.h> #include<stack> using namespace std; /*********************Contest Template***********************/ typedef long long ll; typedef unsigned long long ull; typedef pair<int,int> pii; typedef pair<long long,long long> pll; #define FASTIO ios_base::sync_with_stdio(false);cin.tie(0); 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; const int SPACE=0,NL=1; string exm; inline void showAll(vector<int> &v,int sep){ //0=space,1="\n" for(int &here:v) printf("%d%c",here,(sep)?'\n':' '); } inline void exf(void){ cout<<exm<<"\n"; exit(0); } inline vector<int> int_seperation(int N,int d=10){ vector<int> v; while(N){v.push_back(N%d); N/=d;} reverse(v.begin(),v.end()); return v; } /*********************Contest Template***********************/ const int SIZE= 2000009; set<int> unused; char ans[SIZE]={0},str[1000009]={0}; int main(){ int n; scanf("%d",&n); for(int i=1 ; i<=2000009 ; i++) unused.insert(i); while(n--){ scanf("%s",str+1); int len=strlen(str+1); int m; scanf("%d",&m); for(int i=1 ; i<=m ; i++){ int cur; scanf("%d",&cur); auto it=unused.lower_bound(cur); while(it!=unused.end()){ if(*it>=cur+len) break; ans[*it]=str[*it-cur+1]; it=unused.erase(it); } } } int l; for(int i=2000005 ; i>=1 ; i--){ if(ans[i]!=0) {l=i; break;} } for(int i=1 ; i<=l ; i++){ if(ans[i]==0) printf("a"); else printf("%c",ans[i]); } return 0; } /* */ | cs |
'Problem Solving > String' 카테고리의 다른 글
[CF 1215C] Swap Letters (0) | 2019.09.26 |
---|---|
[Codeforces 1025C] Plasticine zebra (0) | 2019.05.03 |
[Codeforces 1070H] BerOS File Suggestion (0) | 2019.04.21 |
[Codeforces 1138D] Camp Schedule (0) | 2019.03.29 |
1787-문자열의 주기 예측 (0) | 2018.12.03 |