ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 백준 2526번: 싸이클
    구현(Implementation) 2018. 6. 23. 14:51
    반응형

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


    1. 문제

    두 자연수 N과 P를 가지고 다음 과정을 거쳐서 나오는 숫자들을 차례대로 출력해보자. 처음 출력하는 숫자는 N이고, 두 번째 이후 출력하는 숫자들은 N을 곱하고 P로 나눈 나머지를 구하는 과정을 반복하여 구한다. 즉, 먼저 N에 N을 곱하고, 이 수를 P로 나눈 나머지를 두 번째에 출력한다. 다음에는 이 나머지에 N을 곱하고 P로 나눈 나머지를 출력한다. 다음에는 이 나머지에 N을 곱한 후 P로 나눈 나머지를 출력한다. 

    이 과정을 계속 반복해보면 출력되는 숫자들에는 반복되는 부분이 있다. 예를 들어서, N=67, P=31인 경우를 생각해보자. 처음 출력되는 숫자는 67이고, 두 번째로 출력되는 숫자는 67*67 = 4489를 31로 나눈 나머지 25이다. 다음에는 25*67 = 1675를 31로 나눈 나머지 1, 다음에는 1*67 = 67을 31로 나눈 나머지 5가 차례대로 출력된다. 다음에는 5*67 = 335를 31로 나눈 나머지 25가 출력되는데, 이 수는 이미 이전에 출력된 수이다. 이 과정을 그림으로 보이면 다음과 같다.




    2. 알고리즘

    [Figure 1]

    1차원 배열을 선언하여 현재 계산할 값을 대입 한다.

    싸이클에 입력받은 n과 p 의 값으로 다음 값을 계산 한다.

    예제에서는 N = 67, P = 31 임으로 계산 공식에 의해 다음 수는 25가 된다.


    [Figure 2]

    1차원 배열에 다음 인덱스에 현재 계산할 값을 대입 한다.

    figure 1 에 동작을 반복 한다.



    [Figure 3]

    1차원 배열에 다음 인덱스에 현재 계산 할 값을 대입 한다.

    figure 3 도 figure2 처럼 figure 1 에 동작을 반복 한다.


    [Figure 4]

    figure1 동작을 반복 한다.




    [Figure 5]

    위 동작을 반복 하다 보면 순환되는 영역을 확인 할 수 있다.

    계산된 값을 배열에 대입 하면서 순환되는지 확인 하기 위해 검사코드를 추가 해야 한다.

    1
    2
    3
    4
    5
    6
    7
    8
            for (int i = 0; i < sol; i++) {
                // 현재 계산 된 값이 순환 되는지 확인 한다.
                if (arr[i] == cand) {
                    // 순환이 된다면 현재 index로 부터 sol(계산된 수를 저장한 배열의 인덱스) 차이 값을 출력 한다.
                    cout << sol - i << "\n";
                    return 0;
                }
            }    
    cs



    3. 코드

    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
    #include <iostream>
    #include <sstream>
    #include <string>
    #include <algorithm>
    #include <functional>
    #include <vector>
    #include <list>
    #include <queue>
    #include <deque>
    #include <map>
    #include <set>
    #include <stack>
    #include <cstring>
     
    #define MAX_SIZE 100
    #define INF 0x7fffffff
     
    using namespace std;
     
    int dx[4= {1-100};
    int dy[4= {00-11};
     
    int reverse(int x) {
        int rev = 0;
        while(x != 0){
            rev = rev*10 + x%10;
            x = x/10;
        }
        return rev;
    }
     
    int main() {
     
        std::ios::sync_with_stdio(false); cin.tie(0);
     
        int n, p; cin >> n >> p;
        int arr[100={0,};
        int sol = 0;
        arr[sol++= n;
        
        int cand = n;
        while (true)
        {
            cand = (cand * n) % p;
            for (int i = 0; i < sol; i++) {
                // 현재 계산 된 값이 순환 되는지 확인 한다.
                if (arr[i] == cand) {
                    // 순환이 된다면 현재 index로 부터 sol(계산된 수를 저장한 배열의 인덱스) 차이 값을 출력 한다.
                    cout << sol - i << "\n";
                    return 0;
                }
            }
            
            arr[sol++= cand;
        }
        return 0;
    }
     
    cs

    반응형

    댓글

Designed by Tistory.