BOJ : https://www.acmicpc.net/problem/1697

github : https://github.com/junho0956/Algorithm/blob/master/1697/1697/%EC%86%8C%EC%8A%A4.cpp

 

숨바꼭질 같은 경우의 문제는

DFS 보다는 BFS 를 통해서 문제를 해결하여야 합니다.

방문처리를 확인해주는 것은 필수이고, +1 -1 *2 의 순서를 어떻게 줘야할지 고민했는데

*2 같은 값의 변화가 큰 것 부터 주는 것이 맞다고 생각해서 아래와 같이 구현하였고

 

처음에 생각했던 것은 queue 로부터 가장 먼저 발견됬다고 해도

이게 가장 적은 횟수일 보장이 있을까 하는 생각에 저런식으로 구현하였는데

포스팅을 하면서 생각해보니 now == K 가 성립되는 것은

가장 먼저 발견된 것이니 애초에 나머지 큐에 있는 것이 현재 cnt 보다 적을수가 없다는게 성립되고,

continue 가 아니라 break; 를 해주시는게 시간상 빠를 것 같습니다.

 

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
#include <iostream>
#include <queue>
using namespace std;
 
int N, K;
queue<pair<intint> > q;
bool visit[100001];
 
int main() {
    cin >> N >> K;
 
    int Min = 999999;
    q.push({ N,0 });
    while (!q.empty()) {
        int now = q.front().first;
        int cnt = q.front().second;
        q.pop();
 
        if (now > 100000 || now < 0continue;
        if (visit[now]) continue;
        visit[now] = 1;
 
        if (cnt >= Min) continue;
        if (now == K) {
            Min = cnt;
            continue;
        }
 
        if (now != 0 && now < K) q.push({ now * 2, cnt + 1 });
        q.push({ now + 1,cnt + 1 });
        q.push({ now - 1,cnt + 1 });
    }
 
    cout << Min;
    return 0;
}
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by Color Scripter

'algorithm > BOJ' 카테고리의 다른 글

BOJ 13549번 숨바꼭질3  (0) 2020.01.22
BOJ 12851번 숨바꼭질2  (0) 2020.01.22
BOJ 10819번 차이를 최대로  (0) 2020.01.22
BOJ 2410번 2의 멱수의 합  (0) 2020.01.22
BOJ 1451번 직사각형으로 나누기  (0) 2020.01.21

BOJ : https://www.acmicpc.net/problem/10819

github : https://github.com/junho0956/Algorithm/blob/master/10819/10819/%EC%86%8C%EC%8A%A4.cpp

 

완전탐색으로 가능한 모든 경우를 탐색하였으며

범위가 작아서 그런지 빠른 시간내로 해결했습니다.

탐색간 배열을 계속 만들어주어서 수를 확인하고 수가 없다면 삽입 후 넘기는 방식으로 코드하였습니다.

 

next_permutation (조합) 으로 구할 수 있지만 

아직 사용법과 내부 구현을 몰라서 공부 후에 적용해보겠습니다.

 

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
#include <iostream>
#include <algorithm>
using namespace std;
 
 
int arr[8];
int p[101];
int m[101];
int N, Max;
 
void ans(int v[], int index) {
    
    int vv[8];
    for (int i = 0; i < index; i++) vv[i] = v[i];
 
    if (index == N) {
        int total = 0;
        for (int i = 0; i < N - 1; i++) total += abs(vv[i] - vv[i + 1]);
 
        Max = max(Max, total);
        return;
    }
 
    for (int i = 0; i < N; i++) {
        int cnt = 0;
        for (int k = 0; k < index; k++) {
            if (vv[k] == arr[i]) cnt++;
        }
        if (arr[i] == 0 || arr[i] > 0) {
            if (cnt != p[arr[i]]) {
                vv[index] = arr[i];
                ans(vv, index + 1);
            }
        }
        else {
            if (cnt != m[arr[i]*-1]) {
                vv[index] = arr[i];
                ans(vv, index + 1);
            }
        }
    }
}
 
int main() {
    cin >> N;
    for (int i = 0; i < N; i++) {
        cin >> arr[i];
        if (arr[i] == 0) p[0]++;
        else if (arr[i] > 0) p[arr[i]]++;
        else m[arr[i]*-1]++;
    }
 
    for (int i = 0; i < N; i++) {
        int v[8];
        ans(v, 0);
    }
 
    cout << Max;
    return 0;
}

'algorithm > BOJ' 카테고리의 다른 글

BOJ 12851번 숨바꼭질2  (0) 2020.01.22
BOJ 1697번 숨바꼭질  (0) 2020.01.22
BOJ 2410번 2의 멱수의 합  (0) 2020.01.22
BOJ 1451번 직사각형으로 나누기  (0) 2020.01.21
BOJ 1107번 리모컨  (0) 2020.01.21

BOJ : https://www.acmicpc.net/problem/2410

github : https://github.com/junho0956/Algorithm/blob/master/2410/2410/%EC%86%8C%EC%8A%A4.cpp

 

19년도 부산 코딩경시대회에 3번으로 나왔던 문제이다.

그때도 이렇게 풀었었는데 복습할겸 풀어보았다.

 

2의 멱수로 만들수있는 모든 경우의 수를 구할려면

첫 값을 현재 제곱수로 빼보느냐 안빼보느냐로 구분지어서 문제를 해결할 수 있다.

 

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
#include <iostream>
#include <cmath>
#include <algorithm>
#define MOD 1000000000
using namespace std;
 
int N;
int dp[1000001][20];
 
int ans(int num, int p) {
    if (num == 0) {
        return 1;
    }
    if (num < 0 || p < 0return 0;
    if (dp[num][p]) return dp[num][p];
 
    // 현재 값에 대해 2^p 만큼 쓰거나 안쓰고 1로만 쓰거나 둘중하나
    dp[num][p] = ans(num - pow(2, p), p)%MOD + ans(num, p-1)%MOD;
    return dp[num][p];
}
 
int main() {
    cin >> N;
 
    cout << ans(N, 19) % MOD;
    return 0;
}
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by Color Scripter

 

복습 20.02.08

'algorithm > BOJ' 카테고리의 다른 글

BOJ 1697번 숨바꼭질  (0) 2020.01.22
BOJ 10819번 차이를 최대로  (0) 2020.01.22
BOJ 1451번 직사각형으로 나누기  (0) 2020.01.21
BOJ 1107번 리모컨  (0) 2020.01.21
BOJ 1476번 날짜 계산  (0) 2020.01.17

BOJ : https://www.acmicpc.net/problem/1451

github : https://github.com/junho0956/Algorithm/blob/master/1451/1451/%EC%86%8C%EC%8A%A4.cpp

 

직사각형을 3군데로 나눌 수 있는 방법은 다음과 같다.

 

위의 6개 케이스가 나오게 되는데

이 경우를 반복문을 통해 합을 구해서 최댓값을 찾으면 된다.

 

임의의 fst 범위에 대한 값을 빠르게 구해와야 시간초과가 발생하지 않는다.

dp[i][k] = i행 k열 구간의 모든 수의 합이라고 가정할 때

dp[i][k] = dp[i-1][k] + dp[i][k-1] - dp[i-1][k-1] + this[i][k] 의 점화식으로 미리 계산해놓을 수 있으니

f s t 의 반복문 값만 잘 지정해주면 문제 없을 듯 하다.

 

더보기
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
#include <cstdio>
#include <algorithm>
using namespace std;
#pragma warning(disable:4996)
 
int arr[101][101];
long long dp[101][101];
 
int main() {
    int N, M;
    scanf("%d%d"&N, &M);
 
    for (int i = 1; i <= N; i++) {
        for (int k = 1; k <= M; k++) {
            scanf("%1d"&arr[i][k]);
        }
    }
 
    for (int i = 1; i <= N; i++)
        for (int k = 1; k <= M; k++)
            dp[i][k] = dp[i - 1][k] + dp[i][k - 1- dp[i - 1][k - 1+ arr[i][k];
 
    long long ans = 0;
    long long f, s, t;
    
    // case:1
    for (int i = 1; i <= M - 2; i++) {
        f = dp[N][i];
        for (int k = i + 1; k <= M - 1; k++) {
            s = dp[N][k] - f;
            t = dp[N][M] - s - f;
            ans = max(ans, f * s * t);
        }
    }
 
    // case:2
    for (int i = 1; i <= N - 2; i++) {
        f = dp[i][M];
        for (int k = i + 1; k <= N - 1; k++) {
            s = dp[k][M] - f;
            t = dp[N][M] - s - f;
            ans = max(ans, f * s * t);
        }
    }
 
    // case:3
    for (int i = 1; i <= M - 1; i++) {
        f = dp[N][i];
        for (int k = 1; k <= N - 1; k++) {
            s = dp[k][M] - dp[k][i];
            t = dp[N][M] - f - s;
            ans = max(ans, f * s * t);
        }
    }
 
    // case:4
    for (int i = 1; i <= M - 1; i++) {
        for (int k = 1; k <= N - 1; k++) {
            f = dp[k][i];
            s = dp[N][i] - f;
            t = dp[N][M] - f - s;
            ans = max(ans, f * s * t);
        }
    }
 
    // case:5
    for (int i = 1; i <= N - 1; i++) {
        f = dp[i][M];
        for (int k = 1; k <= M - 1; k++) {
            s = dp[N][k] - dp[i][k];
            t = dp[N][M] - f - s;
            ans = max(ans, f * s * t);
        }
    }
 
    // case:6
    for (int i = 1; i <= N - 1; i++) {
        for (int k = 1; k <= M - 1; k++) {
            f = dp[i][k];
            s = dp[i][M] - f;
            t = dp[N][M] - f - s;
            ans = max(ans, f * s * t);
        }
    }
 
    printf("%lld", ans);
    return 0;
}
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by Color Scripter

'algorithm > BOJ' 카테고리의 다른 글

BOJ 10819번 차이를 최대로  (0) 2020.01.22
BOJ 2410번 2의 멱수의 합  (0) 2020.01.22
BOJ 1107번 리모컨  (0) 2020.01.21
BOJ 1476번 날짜 계산  (0) 2020.01.17
BOJ 1744번 수 묶기  (0) 2020.01.17

+ Recent posts