문제: icpc.me/1893
문자열 W가 주어질 때 W를 A의 조건에 맞게 쉬프트하여 문자열 S에서 n번 만큼 쉬프트한 W가 1개일 경우 답에 추가하는 문제이다.
A의 조건의 순서를 dictionary를 이용하여 인덱스로 관리해주고 W를 한번씩 쉬프트 해주면서 S에서 W를 KMP를 이용하여 검색하였을 때 1번만 검색되는 경우만 출력해주면 된다.
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 | #include <cstdio> #include <algorithm> #include <string> #include <iostream> #include <map> #include <vector> using namespace std; int t; string a, w, s; vector<int> pi; vector<int> r; void getpi(string b) { pi.clear(); pi.resize(b.length()); int j = 0; for (int i = 1; i < b.length(); i++) { while (j > 0 && b[i] != b[j]) j = pi[j - 1]; if (b[i] == b[j]) pi[i] = ++j; } } int kmp(string a, string b) { int j = 0; int ret = 0; for (int i = 0; i < a.length(); i++) { while (j > 0 && a[i] != b[j]) j = pi[j - 1]; if (a[i] == b[j]) { if (j == b.length() - 1) { ret++; j = pi[j]; } else j++; } } return ret; } int main() { freopen("input.txt", "r", stdin); scanf("%d", &t); while (t--) { cin >> a >> w >> s; int n = a.length(); r.clear(); map<char, int> mp; map<int, char> rmp; for (int i = 0; i < n; i++) { mp[a[i]] = i; rmp[i] = a[i]; } for (int i = 0; i < n; i++) { if (i) { for (int j = 0; j < w.length(); j++) { w[j] = rmp[(mp[w[j]] + 1) % n]; } } getpi(w); if (kmp(s, w) == 1) r.push_back(i); } if (!r.size()) printf("no solution\n"); else if (r.size() == 1) printf("unique: %d\n", r[0]); else { printf("ambiguous: "); for (int x : r) printf("%d ", x); printf("\n"); } } return 0; } | cs |
'알고리즘 관련 > BOJ' 카테고리의 다른 글
BOJ)1605 반복 부분문자열 (0) | 2017.02.08 |
---|---|
BOJ)1021 회전하는 큐 (0) | 2017.02.06 |
BOJ)9934 완전 이진 트리 (0) | 2017.02.06 |
BOJ)1562 계단 수 (0) | 2017.02.06 |
BOJ)14433 한조 대기 중 (0) | 2017.02.06 |