반응형

문제 출처 :

 

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



알고리즘 분석 :


문제 해결에 필요한 사항

1. 하나의 거쳐야 하는 특정 경로를 지나가는 알고리즘


2. 1번을 이용하기 위한 Dynamic Programming


3. 위의 방식이 아닌 순열, 조합으로 수학적 접근


이 문제는 DP로 접근해도 되고, 고등학교 수학의 순열 조합인 수학적 접근을 하여도 된다.


수학적 접근을 어떻게 하였냐면


aaabb로 이루어진 순열의 모든 경우의 수를 구할 때 5! / (3! * 2!)으로 한다.


이처럼 이 코드에서도 이러한 방법을 이용하였는데


ex ) 15! / 3! * 2!을 하게되면 15!을 먼저하다보면 값이 너무 커져서 

      자료형에서 overflow가 일어 날 수 도 있다.

              따라서 15 / 3 / 2 * 14 / 2 * 13 * 12 * 11 ... 이런식으로 곱하기와 나누기를 동시에 계속 해주는 알고리즘을 제작하였다. 


코드가 다소 복잡할 수 도 있으니, 알고리즘을 어떻게 구성하였는지 확인만 하고 넘어가도 좋다.



소스 코드 : 


< 수학적 접근 > 


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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#include <stdio.h>
 
double result1 = 1;
double result2 = 1;
int n, m, k;
int xy = 0;
int lr = 0;
 
int main()
{
    int map[16][16];
 
 
    int right, down;
 
    int x, y;
    int i, j,t = 1;
    int tmpx, tmpy;
 
 
    scanf("%d %d %d"&n, &m, &k);
 
    // 특정 거쳐야 하는 경로가 없을 경우
    if (k == 0)
    {
        // 가로 세로 총 합을 구한다.
        xy = n - + m - 1;
 
        /*
        ex ) 15! / 3! * 2!을 하게되면 15!을 먼저하다보면 값이 너무 커져서 
             자료형에서 overflow가 일어 날 수 도 있다.
             따라서 15 / 3 / 2 * 14 / 2 * 13 * 12 ... 이런식으로 곱하기와 나누기를 동시에 계속 해주는 알고리즘이다. 
        */
        
        while (xy > 1)
        {
            if (xy > 1)
            {
                result1 = result1 * xy;
 
                if (m - > 1)
                {
                    result1 = result1 / (m - 1);
                    m--;
                }
 
                if (n - > 1)
                {
                    result1 = result1 / (n - 1);
                    n--;
                }
 
                xy--;
            }
        }
        printf("%0.lf", result1);
 
        return 0;
    }
 
 
    for (i = 0; i < n; i++)
    {
        for (j = 0; j < m; j++)
        {
            map[i][j] = t;
 
            if (map[i][j] == k)
            {
                y = i+1;
                x = j+1;
            }
 
            t++;
        }
    }
 
 
    xy = x - + y - 1;
    tmpx = x;
    tmpy = y;
 
    while (xy > 1)
    {
        if(xy > 1)
        {
            result1 = result1 * xy;
 
            if (x - > 1)
            {
                result1 = result1 / (x - 1);
                x--;
            }
 
            if (y - > 1)
            {
                result1 = result1 / (y - 1);
                y--;
            }
 
            xy--;
        }        
    }
 
    right = m - tmpx;
    down = n - tmpy;
 
    lr = right + down;
 
    while (lr > 1)
    {
        if (lr > 1)
        {
            result2 = result2 * lr;
 
            if (right > 1)
            {
                result2 = result2 / (right);
                right--;
            }
 
            if (down > 1)
            {
                result2 = result2 / (down);
                down--;
            }
 
            lr--;
        }
    }
    
    printf("%0.lf", result1 * result2);
 
    return 0;
}
 
//                                                       This source code Copyright belongs to Crocus
//                                                        If you want to see more? click here >>
Crocus








<Dynamic Programming >

.

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
#include <stdio.h>
int table[16][16= { 0, };
 
int main(void) {
    int N, M, K;
    int i, j;
    int x, y;
 
    scanf("%d %d %d"&N, &M, &K);
    x = ((K % M) == 0)?M:(K % M);
    y = ((K % M) == 0)?(K/M) :(K / M) + 1;
 
    table[1][1= 1;
 
    for (i = 1; i <= N; i++) {
        for (j = 1; j <= M; j++) {
            if (i == && j == 1)
                continue;
 
            if (K !=&&((i < y && j > x) || (i > y && j < x))){
                table[i][j] = 0;
            }
            else {
                table[i][j] = table[i - 1][j] + table[i][j - 1];
            }
        }
    }
 
    printf("%d", table[N][M]);
    return 0;
}
 
//                                                       This source code Copyright belongs to Crocus
//                                                        If you want to see more? click here >>
Crocus


반응형

'Applied > 알고리즘 문제풀이' 카테고리의 다른 글

[2669번] 직사각형 네개의 합집합의 면적 구하기  (0) 2016.07.21
[1676번] 팩토리얼 0의 개수  (0) 2016.07.21
[11809번] 충돌  (0) 2016.07.19
[5988번] 홀수일까 짝수일까  (0) 2016.07.10
[10610번] 30  (0) 2016.07.09