반응형

https://www.acmicpc.net/problem/10266

 

10266번: 시계 사진들

상근이는 보통의 시계와는 다른 독특한 시계 사진 두장이 있습니다. 시계는 n개의 동일한 길이와 목적을 가진 시계 바늘들을 가지고 있습니다. 애석하게도 시계의 숫자들은 희미해져 각 시계 바

www.acmicpc.net

 

 

여러 개의 각도를 지닌 두개의 시계를 비교할 때

회전하였을 때 둘이 같아질 수 있는지 비교해야 문제를 해결할 수 있다.

 

시계의 각도가 360,000개 있기 때문에

이를 회전하면서 비교하는 방법을 찾는 것이 중요하다.

 

직접 큐를 만들어서 회전하면서 for문을 돌며 비교할 경우에는 36만 * 36만 번 연산해야 하기 때문에

문제를 해결할 수 없다.

대신 비교할 text를 두번 반복해서 두고 pattern을 그에대해 비교하면

회전을 하지 않고 회전한 효과를 얻을 수 있다.

 

 

문제풀이코드 C++

#include <iostream>

#define MAX_LEN 360'000
using namespace std;

int N;
bool text[MAX_LEN * 2], pattern[MAX_LEN];
int fail[MAX_LEN];

void getFail() {
    int j = 0;

    for (int i = 1; i < MAX_LEN; i++) {
        while (j > 0 && pattern[j] != pattern[i]) {
            j = fail[j - 1];
        }
        if (pattern[j] == pattern[i]) {
            fail[i] = ++j;
        }
    }
}


bool kmp() {
    int j = 0;
    for (int i = 0; i < 2 * MAX_LEN; i++) {
        while (j > 0 && text[i] != pattern[j]) {
            j = fail[j - 1];
        }
        if (text[i] == pattern[j]) {
            if (j == MAX_LEN - 1) {
                return true;
            } else {
                j++;
            }
        }
    }
    return false;
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);

    cin >> N;

    for (int i = 0; i < N; i++) {
        int tmp;
        cin >> tmp;
        text[tmp] = 1;
        text[MAX_LEN + tmp] = 1;
    }

    for (int i = 0; i < N; i++) {
        int tmp;
        cin >> tmp;
        pattern[tmp] = 1;
    }

    getFail();

    if (kmp()) {
        cout << "possible" << '\n';
    } else {
        cout << "impossible" << '\n';
    }
}
반응형

+ Recent posts