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

 

1748번: 수 이어 쓰기 1

첫째 줄에 N(1≤N≤100,000,000)이 주어진다.

www.acmicpc.net

1부터 n까지 숫자를 이어써서 새로운 숫자를 만들면 그 숫자의 길이를 구하는 문제이다.

예를 들어서 n이 12인 경우 123456789101112 이다.

 

이 문제는

1부터 9는 1자리

10부터 99는 2자리

100부터 999는 3자리인 것을 이용해서 풀면 된다.

 

n이 다음 범위보다 작은 경우에는 n까지의 자리만 구하도록 잘 처리해주는 것이 중요하다.

그렇지 않은 경우에는 그냥 (길이 * 9 * i )를 해주면 된다.

문제에 나와있는 120을 예로 들면

 

처음에는

1 * 9 * 1

2 * 9 * 10

3 * ( 120- 100 + 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
#include <iostream>
using namespace std;
 
int main() {
    int n;
    cin >> n;
 
    int ans = 0;
    int len = 0;
    for (int i = 1; i <= n; i*=10) {
        len += 1;
        if (n < i*10) {
            ans += len*(n - i + 1);
            
        }
        else {
            ans += len * 9 * i;
        }
        
    }
 
    cout << ans;
 
    return 0;
}
Colored by Color Scripter
 

'BOJ' 카테고리의 다른 글

[BOJ] 13458. 시험 감독  (0) 2019.07.03
[BOJ] 2529. 부등호  (0) 2019.07.03
[BOJ] 1107. 리모컨  (0) 2019.07.03
[BOJ] 14442. 벽 부수고 이동하기 2  (0) 2019.06.28
[BOJ] 2206. 벽 부수고 이동하기  (0) 2019.06.28

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

 

1107번: 리모컨

첫째 줄에 수빈이가 이동하려고 하는 채널 N (0 ≤ N ≤ 500,000)이 주어진다.  둘째 줄에는 고장난 버튼의 개수 M (0 ≤ M ≤ 10)이 주어진다. 고장난 버튼이 있는 경우에는 셋째 줄에는 고장난 버튼이 주어지며, 같은 버튼이 여러 번 주어지는 경우는 없다.

www.acmicpc.net

어떤 버튼이 고장 났는지 주어졌을 때, 채널 N으로 이동하기 위해서 버튼을 최소 몇 번 눌러야 하는지를 구하는 문제이다.

 

 

먼저 고장나 있는 버튼을 입력받을 때 최대 10개밖에 안되므로 bool 배열에 미리 체크해놓고 검사해야 할 때 이용한다.

 

 

최소 몇 번 이동했는지를 저장해줄 변수 cnt의 초기값으로 n-100을 해서 +나 -버튼만으로 이동하는 경우를 먼저 넣어 놓고 비교를 해나간다.

최소 횟수를 구하기 위해서 모든 채널에서부터 n으로 가는 모든 경우를 구해줄 것이다.

이동할 채널 N은 500,000 까지이지만 버튼이 고장 나 있는 경우 더 뒤의 채널에서 이동하는 게 더 빠를 수 도 있으므로

0번 채널부터 10,000,00번 채널까지의 경우를 모두 해준다.

해당 채널을 누를 때 버튼이 고장 나있는지 매번 확인해주고 고장 나 있는 경우는 누를 수 없으므로 넘어간다.

 

 

고장 난 버튼을 검사하기 위해서는 check함수를 구현하였다. 누를 버튼 번호를 받아서 % 연산을 이용해 한 자리씩 떼준다.

떼낸 숫자가 고장난 버튼일 경우 바로 0을 리턴해주고 아닐 경우에는 길이 값을 늘려준다.

고장 난 버튼이 하나도 없을 경우 길이 값을 리턴한다.

(0인 경우는 나눠줄 수 없으므로 따로 처리해줘야 한다!)

 

 

길이를 받아왔다면 해당 채널로부터 n까지 +나 -로 몇 번 만에 이동하는지를 구해서 더해준 뒤에 최솟값과 비교해주면 된다.

 
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
#include  <iostream>
using namespace std;
int n, m;
bool broken[11];
int check(int num) {
    
    //0을 나눌 수 없으므로 따로 처리
    if (num == 0) {
        if (broken[0]) {
            return 0;
        }
        else {
            return 1;
        }
    }
 
 
    int len= 0;
    while (num > 0) {
 
        //num을 한 자리씩 떼서 검사해준다.
        //하나라도 고장이면 0을 return
        if (broken[num % 10]) {
            return 0;
        }
 
        //고장나지 않았으면 길이 증가하고 검사한 자리는 없애준다.
        len++;
        num /= 10;
    }
 
    //고장난 버튼이 없었다면 길이를 return
    return len;
}
 
 
int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
 
 
    //input
    cin >> n >> m;
    for (int i = 0; i < m; i++) {
        int x;
        cin >> x;
        broken[x] = true;
    }
 
 
    int cnt;
    //+, - 버튼만 사용하는 경우
    cnt = n - 100;
    if (cnt < 0) {
        cnt = -cnt;
    }
 
 
    //모든 번호 에서 n번으로 이동해보면서 몇 번 눌러야하는지 계산
    //번호가 고장나서 누르지 못하는 경우는 넘어간다.
    for (int i = 0; i < 1000000; i++) {
        
        //고장났는지 확인해준다.
        //고장이 나지 않았다면 버튼을 누르는 횟수를 받아온다.
        int len = check(i);
        if (len == 0continue;
 
 
        //현재 i번을 숫자로 누른 상태에서 N까지
        //몇 번 +나 -로 이동해야하는지
        int tmp = n - i;
        if (tmp < 0) {
            tmp = -tmp;
        }
        if (cnt > tmp + len) {
            cnt = tmp + len;
        }
    }
 
    cout << cnt;
    return 0;
}
Colored by Color Scripter
 

'BOJ' 카테고리의 다른 글

[BOJ] 2529. 부등호  (0) 2019.07.03
[BOJ] 1748. 수 이어 쓰기 1  (0) 2019.07.03
[BOJ] 14442. 벽 부수고 이동하기 2  (0) 2019.06.28
[BOJ] 2206. 벽 부수고 이동하기  (0) 2019.06.28
[BOJ] 3055. 탈출  (0) 2019.06.27

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

 

14442번: 벽 부수고 이동하기 2

첫째 줄에 N(1 ≤ N ≤ 1,000), M(1 ≤ M ≤ 1,000), K(1 ≤ K ≤ 10)이 주어진다. 다음 N개의 줄에 M개의 숫자로 맵이 주어진다. (1, 1)과 (N, M)은 항상 0이라고 가정하자.

www.acmicpc.net

 

벽 부수고 이동하기 문제와 거의 같은 문제있은데 이 문제에서는 벽을 K개 까지 부수고 이동하여도 된다.

K의 범위는 K(1 ≤ K ≤ 10) 이렇다.

 

이전 문제에서는 부수지 않은 경우와 부순 경우를 0과 1로 구분하였지만

여기서는 부수지 않은 경우부터 k번 부순 경우까지를 0~k로 구분한다.

즉 z == 0 이어야만 부술수 있는 게 아니고 z 가 k보다 작으면 부술 수 있다.

 

마찬가지로 최솟값을 찾을 때에도 d[n-1][m-1][0]부터 d[n-1][m-1][k]까지 모두 비교해주면 된다.

벽 부수고 이동하기 첫 번째 문제를 풀었다면 쉽게 풀릴 문제이긴 하지만

나는 바보같은 짓을 많이 해서 계속 틀렸었다.

마지막에 최솟값을 구하는 부분의 반복문에서 사용한 i를 사용 안 하고 k로 써놔서 계속 50 퍼쯤에서 틀렸었다ㅠㅠ

 다시 바보같은 실수를 하지 말자는 의미에서 적어놔야겠다...

 

 

또, 이 문제를 통해서 main함수 안에서 크기가 큰 배열을 선언하면 안 된다는 것을 알게 되었다...

c++에 대해서 또 하나 배워간다.

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
#include <cstdio>
#include <queue>
using namespace std;
 
int map[1000][1000];
int d[1000][1000][11];
int dx[] = {0,0,1,-1};
int dy[] = {1,-1,0,0};
 
int main() {
 
   
    int n, m, k;
    scanf("%d %d %d"&n, &m, &k);
 
    for(int i=0; i<n; i++) {
        for(int j=0; j<m; j++) {
            scanf("%1d"&map[i][j]);
        }
    }
 
 
    //시작칸 큐에 넣는다.
    queue<pair<pair<intint>int> > q;
    q.push(make_pair(make_pair(0,0),0));
 
    //시작칸도 포함이므로 1부터 시작
    d[0][0][0= 1;
 
 
    //bfs
    while(!q.empty()) {
        int x = q.front().first.first;
        int y = q.front().first.second;
        int z = q.front().second;
        q.pop();
 
        for(int i=0; i<4; i++) {
            int nx = x+dx[i];
            int ny = y+dy[i];
 
            //범위 체크
            if(nx < 0 || ny < 0 || nx >= n || ny >= m) continue;
            
            //벽인 경우
            //최대 벽을 부술수 있는 횟수인 k번을 넘어가지 않았다면 부수고 이동
            if(map[nx][ny] == 1 && z < k && d[nx][ny][z+1== 0) {
                q.push(make_pair(make_pair(nx,ny),z+1));
                d[nx][ny][z+1= d[x][y][z] + 1;
            } else if(map[nx][ny] == 0 && d[nx][ny][z] == 0) { //길인 경우
                q.push(make_pair(make_pair(nx,ny),z));
                d[nx][ny][z] = d[x][y][z] + 1;
            }
            
        }
        
    }
 
 
    
    //이동 최대값보다 1큰 값을 넣어 놓는다.
    int min =  m*n+1;
 
 
    //벽을 부수지 않고 도착한 경우부터 k번 부순 경우까지 모두 비교해서 최솟값을 찾는다.
    for(int i=0; i<=k; i++) {
        if(d[n-1][m-1][i] != 0 && min > d[n-1][m-1][i]) {
            min = d[n-1][m-1][i];
        }
    }
 
    //처음 저장해놓은 값 그대로이면 도착하지 못한 경우이므로 -1을 출력
    if(min == m*n+1) {
        printf("%d",-1);
    } else {
        printf("%d",min);
    }
 
 
 
    return 0;
}
Colored by Color Scripter
 

'BOJ' 카테고리의 다른 글

[BOJ] 1748. 수 이어 쓰기 1  (0) 2019.07.03
[BOJ] 1107. 리모컨  (0) 2019.07.03
[BOJ] 2206. 벽 부수고 이동하기  (0) 2019.06.28
[BOJ] 3055. 탈출  (0) 2019.06.27
[BOJ] 14501. 퇴사  (0) 2019.06.27

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

 

2206번: 벽 부수고 이동하기

N×M의 행렬로 표현되는 맵이 있다. 맵에서 0은 이동할 수 있는 곳을 나타내고, 1은 이동할 수 없는 벽이 있는 곳을 나타낸다. 당신은 (1, 1)에서 (N, M)의 위치까지 이동하려 하는데, 이때 최단 경로로 이동하려 한다. 최단경로는 맵에서 가장 적은 개수의 칸을 지나는 경로를 말하는데, 이때 시작하는 칸과 끝나는 칸도 포함해서 센다. 만약에 이동하는 도중에 한 개의 벽을 부수고 이동하는 것이 좀 더 경로가 짧아진다면, 벽을 한 개 까지 부수고 이동

www.acmicpc.net

시작 칸에서 마지막 칸까지의 최단 거리를 구하는 문제이기 때문에 bfs로 풀 수 있다.

다른 분의 풀이를 보니 dfs로 엄청 효율적으로 푸셨는데 코드 참고해서 나도 다시 풀어봐야겠다...

 

 

먼저 이 문제에서 중요한 포인트는 벽을 한 개 부수고 이동할 수 있다는 점이다. 이 부분이 이 문제의 어려운 점이다

즉, (x, y)칸에 도착했을 때 그 칸에 그냥 왔는지와 벽을 부수고 왔는지 구분해 주어야한다.

그래서 3차원 배열로 구현했다. 벽을 부수지 않은 경우[x][y][0], 부 순경 우 [x][y][1] 에 이동 경로를 저장했다.

이동할 칸이 벽인 경우, 아직 벽을 부수지 않았고 해당 칸에 아직 방문하지 않았으면 벽을 부수고 이동할 수 있다.

길인 경우에는 그냥 방문하지 않았으면 바로 큐에 넣어준다.

 

 

개인적으로 은근히 헷갈렸던 부분은 이동 경로의 최솟값을 찾아주는 부분이었다.

우선 (n-1, m-1) 칸에 저장되어 있기는 하지만, 벽을 부수고 온 경우가 더 적은 지 벽을 부수지 않고 바로 온경우가 더 적은지

알 수 없으므로 비교해주어야 한다. 그리고 두 곳에 모두 값이 0이라면 -1을 출력해주어야 한다.

나는 먼저 바로 온 경우(d[n-1][m-1][0])을 최솟값(min)으로 해놓고 벽을 부수고 온 경우(d[n-1][m-1][1])가 0이 아닌 경우에 값을 다시 비교해주었다.

 

 

결과적으로 둘 다 0 값을 가지고 있으면 min값도 0이 되므로 도착하지 못한 경우가 되고 -1을 출력한다.

그렇지 않은 경우에는 최솟값을 가지고 있는 min을 출력해준다.

 

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
#include <cstdio>
#include <queue>
using namespace std;
 
int map[1000][1000];
int d[1000][1000][2];
int dx[] = {0,0,1,-1};
int dy[] = {1,-1,0,0};
 
int main() {
 
   
    int n, m;
    scanf("%d %d"&n, &m);
 
    for(int i=0; i<n; i++) {
        for(int j=0; j<m; j++) {
            scanf("%1d"&map[i][j]);
        }
    }
 
 
    //시작 칸을 큐에 넣어준다.
    queue<pair<pair<intint>int> > q;
    q.push(make_pair(make_pair(0,0),0));
 
    //시작칸도 포함이므로 1부터 시작
    d[0][0][0= 1;
 
 
    while(!q.empty()) {
        int x = q.front().first.first;
        int y = q.front().first.second;
        int z = q.front().second;
        q.pop();
 
        for(int i=0; i<4; i++) {
            int nx = x+dx[i];
            int ny = y+dy[i];
 
            //범위 체크
            if(nx < 0 || ny < 0 || nx >= n || ny >= m) continue;
            
            //벽인 경우
            //z == 0 이고 (벽을 부수지 않았고), 벽을 부순상태인 다음 칸에 아직 방문하지 않은 경우
            if(map[nx][ny] == 1 && z == 0 && d[nx][ny][1== 0) {
                q.push(make_pair(make_pair(nx,ny),1));
                d[nx][ny][1= d[x][y][z] + 1;
            } else if(map[nx][ny] == 0 && d[nx][ny][z] == 0) {
 
                //길인 경우 이동할 칸에 방문하지 않았으면 방문
                q.push(make_pair(make_pair(nx,ny),z));
                d[nx][ny][z] = d[x][y][z] + 1;
            }
            
        }
        
    }
 
 
    //마지막칸의 최솟값을 찾아준다.
    int min =  d[n-1][m-1][0];
    if(min != 0) {
        if(d[n-1][m-1][1!= 0 && min > d[n-1][m-1][1]) {
            min = d[n-1][m-1][1];
        }
    } else {
        if(d[n-1][m-1][1!= 0) {
            min = d[n-1][m-1][1];
        }
    }
 
 
    //도착하지 못한 경우 -1을 출력
    if(min == 0){
        printf("%d"-1);
    } else {
        printf("%d",min);
    }     
 
    return 0;
}
Colored by Color Scripter
 

 

 

'BOJ' 카테고리의 다른 글

[BOJ] 1107. 리모컨  (0) 2019.07.03
[BOJ] 14442. 벽 부수고 이동하기 2  (0) 2019.06.28
[BOJ] 3055. 탈출  (0) 2019.06.27
[BOJ] 14501. 퇴사  (0) 2019.06.27
[BOJ] 1697. 숨바꼭질  (0) 2019.06.27

 

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

 

3055번: 탈출

문제 사악한 암흑의 군주 이민혁은 드디어 마법 구슬을 손에 넣었고, 그 능력을 실험해보기 위해 근처의 티떱숲에 홍수를 일으키려고 한다. 이 숲에는 고슴도치가 한 마리 살고 있다. 고슴도치는 제일 친한 친구인 비버의 굴로 가능한 빨리 도망가 홍수를 피하려고 한다. 티떱숲의 지도는 R행 C열로 이루어져 있다. 비어있는 곳은 '.'로 표시되어 있고, 물이 차있는 지역은 '*', 돌은 'X'로 표시되어 있다. 비버의 굴은 'D'로, 고슴도치의 위치는 'S'로 나

www.acmicpc.net

이 문제는 물의 이동시간고슴도치의 이동시간을 비교해주어야 하기 때문에 둘 다 구해준다.

먼저 물이 차는 시간을 구해 놓고 고슴도치를 이동시키는 것이 편하다.

 

먼저 비버굴의 위치와 고슴도치의 위치를 따로 저장해놓고 물일 때는 바로 큐에 넣어준다.

bfs로 물이 차는 시간을 모두 구했으면 고슴도치의 위치를 시작으로 다시 bfs를 시작한다.

 

고슴도치의 경우 다음과 같이 물이 차는 시간과 비교해주는 부분이 중요하다!

 

처음에

 if(w[nx][ny] == s[x][y]+1continue;

이렇게 해줬다가 예제는 다 맞는데 틀려서 고민하다가 이미 더 빠른 시간에 차있는 경우가 생각나서

 

 if(w[nx][ny] <= s[x][y]+1continue;

이렇게 고쳤는데 예제마저 다 틀려버려서 당황했었다.

 

w배열을 방문 확인을 같이 하기 위해 -1로 초기화한 것을 까먹었다ㅠㅠ

최종적으로

 if(w[nx][ny] != -1 && w[nx][ny] <= s[x][y]+1continue;

이렇게 해주면 완벽하다!

 

마지막으로 비버 굴이 초기값이 아니면(도착시간이 저장되어 있으면) 도착시간을 출력해주고

초기값(-1)이면 KACTUS를 출력해준다.


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
#include <iostream>
#include <queue>
#include <cstring>
using namespace std;
 
int main() {
    int r,c;
    scanf("%d %d"&r, &c);
 
    char map[50][50];
    int s[50][50];
    int w[50][50];
 
    int dx[] = {0,0,1,-1};
    int dy[] = {1,-1,0,0};
 
 
    //이동 시간을 저장해줄 배열을 -1로 초기화
    memset(s,-1,sizeof(s));
    memset(w,-1,sizeof(w));
 
    int dochiX, dochiY;
    int beaverX, beaverY;
 
    queue<pair<int,int> > q;
 
 
    //input
    for(int i=0; i<r; i++) {
      
        for(int j=0; j<c; j++) {
            cin >> map[i][j];
 
            //비버굴 위치
            if(map[i][j] == 'D') {
                beaverX = i;
                beaverY = j;
            } else if(map[i][j] == 'S') {
                //고슴도치 위치
                dochiX = i;
                dochiY = j;
            } else if(map[i][j] == '*') {
                //물인 경우
                q.push(make_pair(i,j));
                w[i][j] = 0;
            }
        }
    }
 
    //물 차는 시간 먼저 계산
    while(!q.empty()) {
        int x = q.front().first;
        int y = q.front().second;
        q.pop();
        for(int i=0; i<4; i++) {
            int nx = x+dx[i];
            int ny = y+dy[i];
            
            //범위 체크
            if (nx < 0 || ny < 0 || nx >= r || ny >= c) continue;
            //돌이거나 비버굴인 경우 이동 불가
            if(map[nx][ny] == 'X' || map[nx][ny] == 'D'continue;
            //방문하지 않은 칸이면 방문
            if(w[nx][ny] == -1) {
                q.push(make_pair(nx,ny));
                w[nx][ny] = w[x][y] + 1;
            }
        }
    }
 
    //고슴도치 이동
    q.push(make_pair(dochiX,dochiY));
    s[dochiX][dochiY] = 0;
    while(!q.empty()) {
        int x = q.front().first;
        int y = q.front().second;
        q.pop();
        for(int i=0; i<4; i++) {
            int nx = x+dx[i];
            int ny = y+dy[i];
 
            //범위 체크
            if (nx < 0 || ny < 0 || nx >= r || ny >= c) continue;
 
            //돌인경우 이동 불가
            if(map[nx][ny] == 'X'continue;
 
            //이동하는 곳에 물이 차는 시간이 고슴도치가 이동하는 시간보다 적은 경우
            //초기값을 위에서 -1 로 해줬으므로 주의 해야한다!!
            if(w[nx][ny] != -1 && w[nx][ny] <= s[x][y]+1continue;
 
            //방문하지 않은 경우
            if(s[nx][ny] == -1) {
                q.push(make_pair(nx,ny));
                s[nx][ny] = s[x][y] + 1;
            }
 
        }
    }
 
 
    //비버굴에 도착하지 못하는 경우
    if(s[beaverX][beaverY] == -1) {
        cout << "KAKTUS";
    } else { //도착한 경우 도착한 시간을 출력
        cout << s[beaverX][beaverY];
    }
 
    return 0;
}
Colored by Color Scripter
 
 

'BOJ' 카테고리의 다른 글

[BOJ] 14442. 벽 부수고 이동하기 2  (0) 2019.06.28
[BOJ] 2206. 벽 부수고 이동하기  (0) 2019.06.28
[BOJ] 14501. 퇴사  (0) 2019.06.27
[BOJ] 1697. 숨바꼭질  (0) 2019.06.27
[BOJ] 7569. 토마토 (3차원)  (0) 2019.06.27

https://www.swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AV2b7Yf6ABcBBASw&categoryId=AV2b7Yf6ABcBBASw&categoryType=CODE

 

SW Expert Academy

SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!

www.swexpertacademy.com

N이 20보다 작으므로 완전 탐색을 사용하여 풀었다.

모든 점원의 키를 선택하는 경우와 선택하지 않는 경우를 모두 구해준다.

그중에서 합이 b이상이면 b와의 차이를 구해 최솟값을 비교한다.

 

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
#include <cstdio>
using namespace std;
 
int tall[20];
int n,b,min;
 
void solve(int index, int sum) {
 
    //점원의 키를 선택할지 안할지 모두 정했으면
    if(index >= n) {
        //높이가 b 이상이어야 하므로 b보다 작은경우 return
        if(sum < b) return;
 
 
        //차이가 가장 작은 값을 구한다.
        int tmp = sum-b;
 
        //-1(초기값)이거나 기존의 최솟값보다 작은 경우
        if(min == -1 || min > tmp) {
            min = tmp;
        }
        return;
    }
 
 
    //index번째 점원의 키를 더하지 않는 경우
    solve(index+1, sum);
 
    //index번째 점원의 키를 더하는 경우
    solve(index+1, sum+tall[index]);
}
 
 
int main(){
    int T;
    scanf("%d"&T);
    
    
    for(int tc=1; tc<=T; tc++) {
        min = -1;
        scanf("%d %d"&n, & b);
 
        for(int i=0; i<n; i++) {
            scanf("%d"&tall[i]);
        }
 
        solve(0,0);
        printf("#%d %d\n", tc,min);
 
    }
    return 0;
}
Colored by Color Scripter
 

'SWEA > D4' 카테고리의 다른 글

[SWEA] 9282. 초콜릿과 건포도  (0) 2020.03.04
[SWEA] 1226. [S/W 문제해결 기본] 7일차 - 미로1  (0) 2019.06.27
[SWEA] 7829. 보물왕 태혁  (0) 2019.06.27

https://www.swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AV14vXUqAGMCFAYD&categoryId=AV14vXUqAGMCFAYD&categoryType=CODE

 

SW Expert Academy

SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!

www.swexpertacademy.com

시작점을 큐에 넣고 bfs를 사용해서 도착점에 방문하는지 확인해주면 된다.

도착점을 확인하기 위해 입력받을 때 도착점의 좌표를 따로 저장해둔다.

 

bfs를 할 때 길인 경우(값이 0인 경우)에만 방문을 하게 해서 계속 답이 0이 나왔었다...ㅠㅠ

도착지점인 경우(값이 3인 경우)도 방문하도록 해줘야 한다!

 

결과적으로 도착지점에 방문을 했으면 1을 출력 못했으면 0을 출력하면 된다.

 

 

참고로 미로2 문제도 미로의 크기만 100으로 하면 똑같이 풀 수 있다.

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
#include <cstdio>
#include <queue>
#include <cstring>
using namespace std;
 
int map[16][16];
bool check[16][16];
int dx[] = {0,0,1,-1};
int dy[] = {1,-1,0,0};
 
 
int main() {
    int T = 10;
    int num;
 
 
    for(int tc=1; tc<=T; tc++) {
        scanf("%d",&num);
 
        int endX, endY;
        queue<pair<int,int> > q;
 
        for(int i=0; i<16; i++) {
            for(int j=0; j<16; j++) {
                scanf("%1d"&map[i][j]);
                check[i][j] = false;
 
                //시작점이면 큐에 삽입후 방문 체크
                if(map[i][j] == 2) {
                    q.push(make_pair(i,j));
                    check[i][j] = true;
                } else if(map[i][j] == 3) { //도착점의 좌표를 저장
                    endX = i;
                    endY = j;
                }
            }
        }
 
        while(!q.empty()) {
            int x = q.front().first;
            int y = q.front().second;
            q.pop();
 
            for(int k=0; k<4; k++) {
                int nx = x+dx[k];
                int ny = y+dy[k];
 
                //범위 체크
                if(nx < 0 || ny < 0 || nx >= 100 || ny >= 100continue;
 
                //길이고, 방문하지 않았으면 방문
                if(map[nx][ny] == 0 && check[nx][ny] == false) {
                    q.push(make_pair(nx,ny));
                    check[nx][ny] = true;
                } else if(map[nx][ny] == 3) {
                    //도착점인 경우 방문
                    q.push(make_pair(nx,ny));
                    check[nx][ny] = true;
                }
                 
            }
 
        }
 
        //도착점에 방문했으면 1을 출력
        if(check[endX][endY]) {
            printf("#%d %d\n",tc,1);
        } else { //도착점에 도착하지 못했으면 0을 출력
            printf("#%d %d\n",tc,0);
        }
 
 
    }
 
    return 0;
}
Colored by Color Scripter
 

'SWEA > D4' 카테고리의 다른 글

[SWEA] 9282. 초콜릿과 건포도  (0) 2020.03.04
[SWEA] 1486. 장훈이의 높은 선반  (0) 2019.06.27
[SWEA] 7829. 보물왕 태혁  (0) 2019.06.27

https://www.swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AWtInr3auH0DFASy&categoryId=AWtInr3auH0DFASy&categoryType=CODE

 

SW Expert Academy

SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!

www.swexpertacademy.com

비밀번호 N의 약수를 적어놓아서 약수를 보고 N을 알아내면 된다.

그냥 약수의 최솟값과 최댓값을 곱해주면 되는 쉬운 문제이다.

 

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
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
 
int main() {
    int T;
    scanf("%d"&T);
 
    
    for(int tc=1; tc<=T; tc++) {
        int p;
        scanf("%d"&p);
 
        vector<int> num;
        for(int i=0; i<p; i++) {
            int x;
            scanf("%d",&x);
            num.push_back(x);
        }
 
 
        //최솟값과 최댓값을 찾기 위해 정렬
        sort(num.begin(),num.end());
 
        int ans;
        //맨 앞의 값(최솟값)과 맨 뒤의 값(최댓값)을 곱해준다.
        ans = num.front() * num.back();
        printf("#%d %d\n", tc,ans);
    }
    return 0;
}
Colored by Color Scripter
 

'SWEA > D4' 카테고리의 다른 글

[SWEA] 9282. 초콜릿과 건포도  (0) 2020.03.04
[SWEA] 1486. 장훈이의 높은 선반  (0) 2019.06.27
[SWEA] 1226. [S/W 문제해결 기본] 7일차 - 미로1  (0) 2019.06.27

+ Recent posts