아무생각 없이 문제만 풀 수 있어서 참 좋은 별찍기...

중간중간 새로운 별 모양을 만들어 내면 갱신하도록 하자!

 

찍으려는 별모양을 각 코드 위에 주석처리 해놓았다.

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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
import java.util.Scanner;
 
public class Star {
    public static void main(String[] args) {
 
///////////////////////////별 찍기////////////////////
        Scanner sc = new Scanner(System.in);
        int N = sc.nextInt();
/*
 
*****
*****
*****
*****
*****
 
*/
            
for (int i = 0; i < N ; i++) {
    for (int j = 0; j < N; j++) {
        System.out.print("*");
    }
    System.out.println();
}
System.out.println();        
 
/*
 
**
***
****
***** 
  
*/
 
for(int i = 0; i<N; i++) {
    for (int j = 0; j < i+1; j++) {
        System.out.print("*");
    }
    System.out.println();
}
System.out.println();
 
/*
 
***** 
****
***
**
*
 
*/
 
for (int i = 0; i < N; i++) {
    for (int j = N - i; j > 0; j--) {
        System.out.print("*");
    }
    System.out.println();
}
System.out.println();
 
/*
5.
*
*** 
***** 
******* 
********* 
 
*/
 
 
for (int i = 0; i < N; i++) {
    for (int j = 0; j < 2*+ 1; j++) {
        System.out.print("*");
    }
    System.out.println();
}
System.out.println();
 
/*
 
*
*** 
*****
***
*
    
*/
 
for (int i = 0; i < N; i++) {
    if (i <= N / 2) {
        for (int j = 0; j < 2*+ 1; j++) {
            System.out.print("*");
        }
        System.out.println();
    } 
    else {
        for (int j = 9 - 2*i; j > 0 ; j--) {
            System.out.print("*");
        } 
        System.out.println();
    } 
}
System.out.println();
 
/*
 
* * *
*
* * *
 
*/
 
for (int i = 0; i < N; i++) {
    if(i % 2 == 0) {
        System.out.print("*");
    }
    else {
        for (int j = 0; j < N; j++) {
            if(j % 2 == 0) {
                System.out.print("*");
            }
            else {
                System.out.print(" ");
            }
        }
    }
    System.out.println();
}
System.out.println();
 
// 중복 문제 지우고 이어서
 
/*
 
*****
 ****
  ***
   **
    *
    
*/
 
for (int i = 0; i < N; i++) {
    for (int j = 0; j < i; j++) {
        System.out.print(" ");
    }
    for (int j = 0; j < N - i; j++) {
        System.out.print("*");
    }
    System.out.println();
}
System.out.println();
 
/*
 
    *
   **
  ***
 ****  
*****      
      
*/
 
for (int i = 0; i < N; i++) {
    for (int j = 0; j < N - (i+1); j++) {
        System.out.print(" ");
    }
    for (int j = 0; j < i+1; j++) {
        System.out.print("*");
    }
    System.out.println();
}
System.out.println();
 
 
/*
 
*   *
 * *
  *
 * *
*   *
 
*/
 
for (int i = 0; i < N; i++) {
    for (int j = 0; j < N; j++) {
        if(j == i || j == N-1-i) {
            System.out.print("*");
        }
        else {
            System.out.print(" ");
        }
    }
    System.out.println();
}
System.out.println();
 
 
/*
 
!***!
*!*!*
**!**
*!*!*
!***!
 
*/
 
for (int i = 0; i < N; i++) {
    for (int j = 0; j < N; j++) {
        if(j == i || j == N-1-i) {
            System.out.print("!");
        }
        else {
            System.out.print("*");
        }
    }
    System.out.println();
}
System.out.println();
 
/*
 
!***!
 !*!
  !
 !*!
!***!
 
*/
 
for (int i = 0; i < N; i++) {
    for (int j = 0; j < N; j++) {
        if (i < N / 2) {
            if (j == i || j == N - 1 - i) {
                System.out.print("!");
            } else if (j > i && j < N - 1 - i) {
                System.out.print("*");
            } else {
                System.out.print(" ");
            }
        } else {
            if (j == i || j == N - 1 - i) {
                System.out.print("!");
            } else if (j < i && j > N - 1 - i) {
                System.out.print("*");
            } else {
                System.out.print(" ");
            }
 
        }
    }
    System.out.println();
}
System.out.println();
 
/*
 
!   *
 ! *
  !
 * !
*   !
 
*/
 
for (int i = 0; i < N; i++) {
    for (int j = 0; j < N; j++) {
        if(j == i) {
            System.out.print("!");
        }
        else if(j == N-1-i) {
            System.out.print("*");
        }
        else {
            System.out.print(" ");
        }
    }
    System.out.println();
}
System.out.println();
 
 
/*
 
  *
 * *
*   *
 * *
  *
 
*/
 
for (int i = 0; i < N; i++) {
    for (int j = 0; j < N; j++) {
        if(i < N/2) {    
            if(j == N/2 - i || j == N/2 +i) {
                System.out.print("*");
            }
            else {
                System.out.print(" ");
            }
        }
        else { 
            if(j == N/2 - (N-1+ i || j == N/2 + (N-1- i ) {
                System.out.print("*");
            }
            else {
                System.out.print(" ");
            }
        }
    }
    System.out.println();
}
System.out.println();
/*
 
  *  
 ***
*****
 ***
  * 
 
 */
 
for (int i = 0; i < N; i++) {
    for (int j = 0; j < N; j++) {
        if(i < N/2) {    
            if(j >= N/2 - i && j <= N/2 +i) {
                System.out.print("*");
            }
            else {
                System.out.print(" ");
            }
        }
        else { 
            if(j >= N/2 - (N-1+ i && j <= N/2 + (N-1- i ) {
                System.out.print("*");
            }
            else {
                System.out.print(" ");
            }
        }
    }
    System.out.println();
}
System.out.println();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
    }
}
cs

 

 

https://swexpertacademy.com/main/solvingProblem/solvingProblem.do

 

SW Expert Academy

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

swexpertacademy.com

이 문제는 2가지 방법으로 풀 수 있다.

1. 별 찍기하듯이

2. 델타 탐색

 

먼저, 문제에서 농작물을 수확할 수 있는 정사각형 마름모 형태의 별을 찍어보면,

N = 7일 때

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
for (int i = 0; i < N; i++) {
    for (int j = 0; j < N; j++) {
        if(i < N/2) {    
            if(j >= N/2 - i && j <= N/2 +i) {
                System.out.print("*");
            }
            else {
                System.out.print(" ");
            }
        }
        else { 
            if(j >= N/2 - (N-1+ i && j <= N/2 + (N-1- i ) {
                System.out.print("*");
            }
            else {
                System.out.print(" ");
            }
        }
    }
    System.out.println();
}
cs

 

이를 이용해 문제를 풀어보자. 농작물 수확해서 얻는 이익을 profit이라는 변수라고 하였다.

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
import java.util.Scanner;
 
public class List_Sequantial {
 
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
 
        int T = sc.nextInt();
        for (int tc = 0; tc < T; tc++) {
 
            int N = sc.nextInt();
            int[][] farm = new int[N][N];
 
            // 한 줄씩 입력 받아서 char로 하나씩 쪼갠다.
            // sc.nextInt()로 String 14054을 입력받고,
            // toCharArra()로 char 1, char 4...char 4의 배열로 바꿔준다.
            // 즉, ['1', '4', '0', '5', '4']가 되는 것이다.
            for (int i = 0; i < N; i++) {
                char[] tempArr = sc.next().toCharArray();
                for (int j = 0; j < N; j++) {
                    farm[i][j] = tempArr[j] - '0';
                }
            }
            int profit = 0
            for (int i = 0; i < N; i++) {
                for (int j = 0; j < N; j++) {
                    if (i < N / 2) {
                        if (j >= N / 2 - i && j <= N / 2 + i) {
                            profit = profit + farm[i][j];
                        }
                    } else {
                        if (j >= N / 2 - (N - 1+ i && j <= N / 2 + (N - 1- i) {
                            profit = profit + farm[i][j];
                        }
                    }
                }
            }
            System.out.println("#" + (tc+1+ " " + profit);
        }
    }
}
 
cs

 

이번엔 델타 탐색을 통해 문제를 풀어보도록 한다.

먼저 N=5일때, 수확이 가능한 부분을 색칠해서 나타내면(노란색 부분)

N*N 2차원 배열의 중앙을 기준으로 생각해보자.

중앙을 기준으로 2칸 이동을 한 경우에만 수확이 가능함을 알 수 있다.

즉, 위로 두칸이든 위로 한칸 오른쪽 한칸이든 이동한 횟수 또는 칸수가 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
28
29
30
31
32
33
34
35
36
import java.util.Scanner;
 
public class Solution {
 
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
 
        int T = sc.nextInt();
        for (int tc = 0; tc < T; tc++) {
 
            int N = sc.nextInt();
            int[][] farm = new int[N][N];
 
            // 한 줄씩 입력 받아서 char로 하나씩 쪼갠다.
            // sc.nextInt()로 String 14054을 입력받고,
            // toCharArra()로 char 1, char 4...char 4의 배열로 바꿔준다.
            // 즉, ['1', '4', '0', '5', '4']가 되는 것이다.
            for (int i = 0; i < N; i++) {
                char[] tempArr = sc.next().toCharArray();
                for (int j = 0; j < N; j++) {
                    farm[i][j] = tempArr[j] - '0';
                }
            }
            int profit = 0;
            for (int i = 0; i < N; i++) {
                for (int j = 0; j < N; j++) {
                    if ((Math.abs(i - N / 2+ Math.abs(j - N / 2)) <= N / 2) {
                        profit = profit + farm[i][j];
                    }
                }
            }
            System.out.println("#" + (tc+1+ " " + profit);
        }
    }
}
 
cs

 

 

https://swexpertacademy.com/main/solvingProblem/solvingProblem.do

 

SW Expert Academy

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

swexpertacademy.com

델타 탐색을 이용하여 풀어본다.

숫자가 시계방향으로 이루어져 있으므로,

탐색 방향은 (오른쪽, 아래, 왼쪽, 위) 순서대로 반복될 것이다.

아래 N = 4일 경우, 달팽이의 모습을 보자.

1 2 3 4
12 13 14 5
11 16 15 6
10 9 8 7

N*N의 2차원 배열에서 원소 1이 존재하는 위치를 기준으로 탐색해나가면서 숫자를 입력해줘야 하는데,

중요하게 생각할 포인트는 "언제 방향을 바꾸는가" 이다.

처음 위치부터 생각해보자. 처음 위치(배열의 [0][0] 위치)에 1을 지정하고 시작하도록 한다.

처음위치에서는 아래 화살표 방향과 같이 오른쪽으로 탐색해 나가면서 숫자를 1씩 더해 입력한다.

그런데, 아래와 같이 4까지 입력하고 나면, 5를 입력하기 위해서는 탐색 방향을 오른쪽이 아닌 아래 방향으로 바꾸어야 한다.

일단 어떤 조건을 통해 방향을 바꾸었다고 가정하고, 진행해보면서 어느 지점에서 방향이 바뀌어야 하는지 살펴보면, 

1. 같은 방향으로 탐색시 다음 차례에서 배열의 범위를 벗어날 때,

2. 같은 방향으로 탐색시 다음 차례에 숫자가 존재할 때, (다음 차례에 숫자가 존재한다는 것을 어떻게 처리?)

이제, 각 조건에 대해 어떻게 코드를 작성할지 살펴보자.

1번 조건에 대해서는 다음 탐색 위치(인덱스)가 0이상이고 N-1을 초과하면 안되므로, 인덱스 값이 N보다 작아야 한다는 조건을 이용하도록 한다.

2번 조건에 대해서는 다음 탐색 위치에 숫자가 존재한다는 조건을 달기 위해 그 위치의 값이 0이면 방향을 바꾸어야 한다는 조건을 이용한다.(왜냐하면 int배열을 생성하면 기본적으로 원소들이 0이기 때문이다)

 

아래 코드와 주석을 살펴보자.

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
import java.util.Scanner;
 
public class Solution {
 
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
 
        int T = sc.nextInt();
        for (int tc = 1; tc <= T; tc++) {
 
            int N = sc.nextInt();
            int[][] snail = new int[N][N];
            int[] dr = { 010-1 };
            int[] dc = { 10-10 }; // 우 하 좌 상
            int n = 0// dr, dc의 index 역할
 
            int row = 0// 현재 행 인덱스
            int col = 0// 현재 열 인덱쇼
 
            snail[0][0= 1// 처음 위치 값 1 지정
            int w = 1;
            //총 N-1번 탐색
            while (w < N * N) { 
                int nr = row + dr[n]; //이동 후 행 인덱스
                int nc = col + dc[n]; //이동 후 열 인덱스
                //nr, nc가 0이상 N-1이하여야 인덱스 범위 초과하지 않고,
                //다음 위치에 0이 존재해야 방향을 유지한다.
                if (nr >= 0 && nr < N && nc < N && nc >= 0 && snail[nr][nc] == 0) {
                    snail[nr][nc] = ++w; //이전의 w값보다 하나 증가된 w를 대입하고, w 자신도 1증가
                    row = nr;
                    col = nc;
                } else {
                    n = (n + 1) % 4//4가지의 방향이 있으므로 4로 나눈 나머지를 이용해 돌린다.
                }
            }
            System.out.println("#" + tc);
            for (int i = 0; i < N; i++) {
                for (int j = 0; j < N; j++) {
                    System.out.print(snail[i][j] + " ");
                }
                System.out.println();
            }
        }
    }
}
 
cs

 

 

https://swexpertacademy.com/main/solvingProblem/solvingProblem.do

 

SW Expert Academy

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

swexpertacademy.com

문제를 푸는 것에 있어서 가장 핵심은 배열의 index의 활용이다.

점수는 0점~100점, 점수들 중에서 최빈값을 구하는 것.

예를들어, 각 점수마다 임의로 빈도수를 나타낸다고 가정해보자.

0점 1점 2점 3점 4점 ...  98점 99점 100점

1번 4번 6번 2번 5번 ...  3번   20번     1번

위 두 줄을 보면 뭐가 떠오르는가? 

"배열의 원소와 각 원소에 대한 인덱스"

즉, 점수마다의 빈도수를 원소로 갖고, 인덱스 번호가 0부터 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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
import java.util.Scanner;
 
public class Solution {
 
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int T = sc.nextInt();
 
        for (int k = 0; k < T; k++) {
            int t = sc.nextInt();
            //1000명의 학생의 점수 입력
            int[] arr = new int[1000];
            for (int i = 0; i < arr.length; i++) {
                arr[i] = sc.nextInt();
            }
            //0점 ~ 100점의 빈도수를 셀 배열 생성
            int[] cnt = new int[101]; // 0점 ~ 100점(배열의 길이: 101)
            for (int i = 0; i < arr.length; i++) {
                for (int j = 0; j < 101; j++) {
                    if (arr[i] == j) {
                        cnt[j]++;
                    }
                }
            }
            //가장 큰 빈도수를 찾아, 그 빈도수에 해당되는 점수(인덱스) 출력하기
            //이때, 가장 큰 빈도수가 여러 개이면 가장 높은 점수를 출력해야하는데,
            // 아래 max, cnt[i] 비교시 <만 입력하게 되면, 더 높은 점수(인덱스)에서 동일한 빈도수를 가지더라도 출력이 안되므로
            // max <= cnt[i]로 처리한다.
            int max = cnt[0];
            int answer = 0;
            for (int i = 0; i < cnt.length; i++) {
                if (max <= cnt[i]) { 
                    max = cnt[i];
                    answer = i;
                } 
            }
            System.out.println("#" + t + " " + answer);
        }
    }
 
}
 
cs

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
28
29
30
import java.util.Scanner;
 
public class Solution {
 
    public static void main(String[] args) {
 
        Scanner sc = new Scanner(System.in);
        int T = sc.nextInt();
 
        for (int k = 0; k < T; k++) {
            int t = sc.nextInt();
            //점수 입력 및 빈도수 배열 생성, 빈도수 나타내기
            int[] cnt = new int[101];
            for (int i = 0; i < 1000; i++) {
                int score = sc.nextInt();
                cnt[score]++;
            } 
            //가장 큰 빈도수 찾아, 점수 출력하기
            int maxScore = 0;
            for(int score=0; score<cnt.length; score++){
                if(cnt[maxScore] <= cnt[score]) {
                    maxScore = score; 
                }
            }
            System.out.println("#" + t + " " + maxScore);
        } 
 
    }
}
 
cs

 

Binary Search란 정렬되어 있는 데이터에서 원하는 값을 찾는 방법이다.

대상 데이터의 중앙값과 찾고자하는 값을 비교해 데이터의 크기를 절반씩 줄이면서 찾는데, 

이때 자료는 반드시 정렬된 상태여야 한다.(예를 들면, 오름/내림차순)

 

정렬방법에 대해 먼저, 대략적으로 얘기해보면,

1. 자료 중앙에 있는 원소를 고름

2. 중앙 원소의 값과 찾고자 하는 값을 비교

3. 찾고자 하는 값이 중앙 원소의 값보다 작으면 자료의 왼쪽 데이터에 대해서 새로 탐색하고,

크다면 자료의 오른쪽 데이터에 대해 새로 탐색한다.

4. 이를 반복한다.

 

핵심은 탐색의 범위를 반복적으로 반으로 줄이는 것이다.

 

이제 자세히 알아보자.

오름차순으로 정렬된 배열 arr = {2, 4, 7, 9, 11, 19, 23}이 있고, 이중 7을 검색하려고 한다.

먼저, 배열의 중앙 원소는 9이다.

직관적으로 중앙 원소가 무엇인지 알 수 있긴 하나, 그 값을 찾는 방법을 다시 말하자면,

맨 처음 index = 0, 마지막 index = 배열의 길이 - 1이므로 중앙 원소가 존재하는 index는 (0+ 배열의 길이 - 1) / 2가 된다.

즉, 배열 arr는 배열의 길이가 7이므로 중앙 원소가 존재하는 index는 (7-1) / 2 == 3.

따라서 중앙값은 arr[3]인 9이다.

이제 중앙 원소의 값(9)과 찾고자 하는 값(7)을 비교해보자.

찾고자 하는 값이 중앙값보다 왼쪽에 있으므로, 중앙값의 왼쪽 데이터에 대해 새로 탐색해야 한다.

이제, 맨 처음 index는 0, 맨 마지막 index는 2가 됐다.

이때의 중앙값은 index 1의 위치의 값인 4가 된다.

중앙값(4)와 찾는 값(7) 중에서 찾는 값이 더 크므로,

즉 찾는 값이 중앙값보다 오른쪽에 있으므로, 중앙값의 오른쪽 데이터에 대해 새로 탐색해야 한다.

그런데, 탐색 범위가 인덱스가 2인 값뿐이고, 찾는 값과 중앙값이 일치하므로 탐색을 성공한 것이다.

 

이제 코드를 작성하여 알아보도록 하자.

위와 같은 순서로,

1. 탐색의 대상이 되는 자료들이 정렬되어 있는 배열 arr[low]부터 arr[high]사이에 들어있다고 하자.

 - 배열의 길이가 N이라고 하면, low는 0번 인덱스, high는 N-1번 인덱스이다.

 

2. 중간값의 인덱스를 mid라고 하자. 

 - mid == (low+high) / 2이다.

 

3. 찾는 값(key값)이 arr[mid]보다 큰지, 작은지를 비교한다.

 - key < arr[mid]: 찾는 값이 중간값의 왼쪽에 존재하는 경우이므로 high를 mid-1로 만든다.

 - key > arr[mid]: 찾는 값이 중간값의 오른쪽에 존재하는 경우이므로 low를 mid+1로 만든다.

 - key == arr[mid]: 찾는 값을 찾음. 중간값을 return해주면 됨

 

4. low > high가 될 때까지 반복하면서 key값을 찾는다. 

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
import java.util.Arrays;
 
public class List_BianrySearch {
    
    static int[] arr = {4,9,11,23,2,19,7};
    public static void main(String[] args) {
        Arrays.sort(arr);
        System.out.println(Arrays.toString(arr));
        System.out.println(binarySearch(70, arr.length - 1));
        
    }
    
    // key - 구하고자 하는 값
    // mid - 중간값에 해당하는 인덱스
    // low - 0번 인덱스
    // high - (배열의 길이 - 1)번 인덱스
    
    static int binarySearch(int key, int low, int high) {
        
        //중간값
        int mid;
        while(low <= high) {
            mid = (low + high) / 2;
            if(key == arr[mid]) {
                return mid;
            } else if(key < arr[mid]) { //중간값의 왼쪽에 해당
                high = mid - 1//하나를 빼주면 왼쪽에서 가장 큰 값이 되니까
            } else { //중간값의 오른쪽에 해당
                low = mid + 1//하나를 더하면 오른쪽에서 가장 작은 값이 되니까
            }
        }
        return -1//탐색 실패
        
    }
    
}
 
cs

 

< 코드 작성++ >

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
import java.util.Arrays;
import java.util.Scanner;
 
public class Main {
 
    // 이진 탐색 소스코드 구현(반복문) -- 오름차순으로 정렬되어 있는 상태에서 이진 탐색!
    public static int binarySearch(int[] arr, int target, int start, int end) {
        /*
         * target: 찾고자 하는 값 start: 탐색 범위 내의 시작 인덱스 end: 탐색 범위 내의 끝 인덱스 mid: start와 end의 중간 위치 인덱스
         */
        while (start <= end) {
            int mid = (start + end) / 2;
 
            // target이 중간점에 위치할 경우 중간점의 인덱스를 반환한다.
            if (arr[mid] == target) {
                return mid;
            }
            // 오름차순 정렬상태이므로 target이 중간점보다 왼쪽에 위치한 경우 왼쪽 범위만 확인
            // end = mid - 1
            else if (arr[mid] > target) {
                return binarySearch(arr, target, start, mid - 1);
            }
            // target이 중간점보다 오른쪽에 위치한 경우 오른쪽 범위만 확인
            // start = mid + 1
            else {
                return binarySearch(arr, target, mid + 1, end);
            }
            // 못 찾은 경우 -1 반환
        }
        return -1;
 
    }
 
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        
        // 원소의 개수(n)와 찾고자 하는 값(target)을 입력받기
        int n = sc.nextInt();
        int target = sc.nextInt();
                
        // 전체 원소 입력 받기 + 오름차순 정렬하기
        int[] arr = new int[n];
        for (int i = 0; i < arr.length; i++) {
            arr[i] = sc.nextInt();
        }
        Arrays.sort(arr);
        
        // 이진 탐색 수행 결과 출력
        int result = binarySearch(arr, target, 0, n-1);
        if(result == -1) {
            System.out.println("찾는 값이 존재하지 않습니다.");
        }
        else {
            System.out.println("찾는 값의 인덱스는 " + result + "입니다." );
        }
        
    }
}
cs

 

 

 

 

'알고리즘 및 코테' 카테고리의 다른 글

배열에 정수를 입력할 때마다 정렬하여 출력하기  (0) 2023.01.27
정렬 - Selection Sort  (0) 2023.01.10
정렬 - Bubble Sort  (0) 2023.01.09

https://swexpertacademy.com/main/solvingProblem/solvingProblem.do

 

SW Expert Academy

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

swexpertacademy.com

풀이를 하면서, 문제를 푸는 것 외에 확장된 생각을 함께 정리한다.

문제를 푸는 흐름은

1. 최댓값, 최솟값을 구한다.

2. 배열의 원소들의 총 합에서 최댓값, 최솟값을 빼준다.

3. 뺀 결과를 8(전체 원소 개수 - 최댓값 1개 - 최솟값 1개)

라고 생각을 했고, 

출력을 위해서

1. int를 double로 형변환하기 위해 8로 나누는 것이 아닌 8.0(8.0은 double, 8.0f는 float이므로)으로 나눠줬다.

2. 소수점 첫째자리에서 반올림 하기 위해, 반올림 하기 위한 변수에 0.5를 더하고 int로 형변환하여 버림을 해줬다.

(예를 들어, 13.4라면 0.5를 더해 13.9가 되고, int형변환을 통해 13이 되지만,

13.5라면 0.5를 더해 14.0이 되고, int형변환을 통해 14가 되기 때문이다.)

 

그 Solution은 다음과 같다.

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
import java.util.Scanner;
 
public class Solution {
 
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
 
        int T = sc.nextInt();
        for (int n = 1; n <= T; n++) {
 
            int[] arr = new int[10];
            for (int i = 0; i < 10; i++) {
                arr[i] = sc.nextInt();
            }
            // 최댓값 max 구하기
            int max = arr[0];
            for (int i = 0; i < 10; i++) {
                if (arr[i] > max) {
                    max = arr[i];
                }
            }
            // 최솟값 min 구하기
            int min = arr[0];
            for (int i = 0; i < 10; i++) {
                if (arr[i] < min) {
                    min = arr[i];
                }
            }
            // 배열 원소 전체 합 구하기
            int sum = 0;
            for (int i = 0; i < 10; i++) {
                sum = sum + arr[i];
            }
            int sum1 = sum - max - min;
            double ave = sum1 / 8.0//int를 double로 형변환
            // 소수 첫째자리에서 반올림을 하기 위해 0.5를 더하고 int로 형변환
            System.out.println("#" + n + " " + (int) (ave + 0.5));
        }
    }
 
}
 
cs

하지만, 

위의 생각에서 좀 더 자세히 파고들면,

최댓값과 최솟값을 각각 1개씩만 가지는 배열만 input 데이터에 포함되어 있다는 확신이 있는가? 라는 생각이 들게 된다.

즉, 어떤 배열이 {1,2,3,4,5,6}여서 최댓값이 6, 최솟값이 1이라고 했을 때, 위와 같은 Solution대로 결과를 출력할 수 있지만, 

어떤 배열이 {1,1,2,3,4,5,6,6}이라면 최댓값, 최솟값이 2개씩 존재하게 되므로 단순히 전체 배열 원소의 개수에서 2를 빼준 값을 통해 평균을 구하려고 접근해서는 안된다.

따라서, 아래 Solution은 최댓값, 최솟값이 중복해서 존재하는 경우 그 개수를 고려해준 결과이다.

위, 아래 둘다 동일한 출력 결과가 나타나지만, 이것은 input 데이터가 중복된 최댓값 혹은 최솟값이 존재하지 않았기 때문이었을 뿐이다. 

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
import java.util.Scanner;
 
public class Solution {
 
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
 
        int T = sc.nextInt();
        for (int n = 1; n <= T; n++) {
 
            int[] arr = new int[10];
            for (int i = 0; i < 10; i++) {
                arr[i] = sc.nextInt();
            }
            // 최댓값 max 구하기
            int max = arr[0];
            for (int i = 0; i < 10; i++) {
                if (arr[i] > max) {
                    max = arr[i];
                }
            }
            // 최솟값 min 구하기
            int min = arr[0];
            for (int i = 0; i < 10; i++) {
                if (arr[i] < min) {
                    min = arr[i];
                }
            }
            // 배열 원소 전체 합 구하기
            int sum = 0;
            for (int i = 0; i < 10; i++) {
                sum = sum + arr[i];
            }
            // 최댓값, 최솟값이 몇개씩 들어있는지 확인
            // 각각 1개씩 있다면 전체 원소 10개에서 최댓값, 최솟값 1개씩 뺀 8개에 대해 평균값을 구하면 되지만,
            // 1 1 2 3 4 5 5처럼 최댓값, 최솟값이 1개보다 많다면 그 개수만큼 더 빼줘야 하기 때문이다.
            int maxCount = 0, minCount = 0;
            for (int i = 0; i < arr.length; i++) {
                if (max > arr[i]) {
                    maxCount++;
                }
                if (min < arr[i]) {
                    minCount++;
                }
            }
            // 10 - maxCount는 최댓값의 개수, 10 - minCount는 최솟값의 개수
            int sum1 = sum - max * (10 - maxCount) - min * (10 - minCount);
            int count = 10 - (10 - maxCount) - (10 - minCount);
            double ave = sum1 / (double) count;
            // 소수 첫째자리에서 반올림을 하기 위해 0.5를 더하고 int로 형변환
            System.out.println("#" + n + " " + (int) (ave + 0.5));
        }
    }
 
}
 
cs

 

https://swexpertacademy.com/main/solvingProblem/solvingProblem.do

 

SW Expert Academy

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

swexpertacademy.com

오름차순으로 정렬하는 것이므로 두 가지 방식으로 풀어보고자 한다.

1. 버블 정렬

2. 선택 정렬

 

Theme. 버블 정렬 Solution

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
import java.util.Scanner;
 
public class Solution {
 
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
 
        int T = sc.nextInt();
        for (int n = 1; n <= T; n++) {
            int tmp;
            int t = sc.nextInt();
            int[] arr = new int[t];
            for (int i = 0; i < t; i++) {
                arr[i] = sc.nextInt();
            }
            for (int i = 0; i < arr.length - 1; i++) {
                for (int j = 0; j < arr.length - 1 - i; j++) {
                    if (arr[j] > arr[j + 1]) {
                        tmp = arr[j + 1];
                        arr[j + 1= arr[j];
                        arr[j] = tmp;
                    }
                }
            }
 
            System.out.print("#" + n + " ");
            for (int i = 0; i < arr.length; i++) {
                System.out.print(arr[i] + " ");
            }
            System.out.println();
        }
    }
 
}
 
cs

 

Theme. 선택 정렬 Solution

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
import java.util.Scanner;
 
public class Solution {
 
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
 
        int T = sc.nextInt();
        for (int n = 1; n <= T; n++) {
            int tmp;
            int t = sc.nextInt();
            int[] arr = new int[t];
            for (int i = 0; i < t; i++) {
                arr[i] = sc.nextInt();
            }
            for (int i = 0; i < arr.length - 1; i++) {
                int minIdx = i;
                for (int j = i+1; j < arr.length; j++) {
                    if (arr[minIdx] > arr[j]) {
                        minIdx = j;
                    }
                }
                tmp = arr[minIdx];
                arr[minIdx] = arr[i];
                arr[i] = tmp;
            }
 
            System.out.print("#" + n + " ");
            for (int i = 0; i < arr.length; i++) {
                System.out.print(arr[i] + " ");
            }
            System.out.println();
        }
    }
 
}
cs

 

 

 

선택 정렬(Selection Sort)는 배열의 원소 중에서 원하는 위치에 놓을 데이터를 찾아 선택하는 것

 

어떤 배열을 오름차순으로 정렬하고 싶다고 가정하고 설명하도록 한다.

int[] array = {5, 9, 1, 7, 2}; 인 배열 array가 있다고 하자.

정렬을 할 때마다 배열의 맨 앞부터의 위치들에 최솟값들이 하나씩 이동하게 되므로

이미 최솟값을 이동시킨 위치는 고려하지 않고, 그 다음 위치들 중에서 최솟값을 찾는다.

 

즉, 전체적인 과정을 설명하면,

 

1. 배열의 각 원소 중에서 최솟값을 찾고, 이를 array[0]과 자리를 바꾼다. (swap)

2. array[0]을 제외한 나머지 원소들 중에서 최솟값을 찾아 array[1]과 자리를 바꾼다.

3. array[2], array[3]....도 위의 방법대로 반복한다.

 

이때, (배열의 길이 - 1)만큼만 최솟값을 찾는 cycle을 진행하면 되는데, 

위의 예시에서 총 5개의 데이터 중에서 4개의 데이터를 정렬했다는 것은 이미 마지막 데이터는 정렬이 되었다는 의미이기 때문이다. (최솟값을 찾고 나머지 값들과 비교하여 정렬했으므로 2개씩 비교가 되었기 때문) 

 

이를 코드를 작성하여 비교해보자.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import java.util.Arrays;
 
public class Selection_Sort {
    public static void main(String[] args) {
        // 선택정렬을 통해 오름차순으로 정렬
        int[] array = { 59172 };
        // 최솟값을 갖는 index를 찾아 그 index 자리의 값과 array[i]값을 바꿔준다.
        for (int i = 0; i < array.length - 1; i++) {
            int minIdx = i;
            for (int j = i + 1; j < array.length; j++) {
                if (array[minIdx] > array[j]) {
                    minIdx = j;
                }
            }
            int tmp = array[i];
            array[i] = array[minIdx];
            array[minIdx] = tmp;
        
        }
        System.out.println(Arrays.toString(array));
    }
}
 
cs

내림차순도 같은 논의로 진행해보면, (부등호의 방향만 반대)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import java.util.Arrays;
 
public class Selection_Sort {
    public static void main(String[] args) {
        // 선택정렬을 통해 내림차순으로 정렬
        int[] array = { 59172 };
        // 최댓값을 갖는 index를 찾아 그 index 자리의 값과 array[i]값을 바꿔준다.
        for (int i = 0; i < array.length - 1; i++) {
            int maxIdx = i;
            for (int j = i + 1; j < array.length; j++) {
                if (array[maxIdx] < array[j]) {
                    maxIdx = j;
                }
            }
            int tmp = array[i];
            array[i] = array[maxIdx];
            array[maxIdx] = tmp;
        
        }
        System.out.println(Arrays.toString(array));
    }
}
 
cs

그 결과, {9, 7, 5, 2, 1}로 내림차순 정렬이 됨을 확인할 수 있다.

 

두 개의 인접한 원소(값)을 비교하여 정렬하는 것

버블 정렬에 대해 알아보기 위해 배열을 오름차순으로 나타내는 것을 기준으로 한다.

간단하게 말하면, 두개씩 값을 비교하고, 조건에 맞게 swap하는 것이다.

 

1. array[0]에서부터 비교(첫번째 cycle)

int[] array = { 1, 5, 9, 3, 7, 1, 0}; 인 배열 array을 오름차순으로 정렬하는 것을 예로 들어 설명하도록 한다.

먼저, array[0]과 array[1]을 비교했을 때, array[0] < array[1]이므로 swap할 필요가 없다.

같은 방식으로, array[1]와 array[2] 또한 swap할 필요가 없다.

이때, array[2] > array[3]이므로 두 원소를 swap해야 한다.

같은 방식으로 진행한 결과는 다음과 같다.

첫 번째 cycle 결과 배열 array는 { 1, 5, 3, 7, 1, 0, 9 }가 되었다.

 

2. 두번째 사이클

3. 세번째 사이클

4. 네번째 사이클

5. 다섯번째 사이클

6. 여섯번째 사이클

최종적으로 버블 정렬을 통해 오름차순 정렬을 한 결과는 {0, 1, 1, 3, 5, 7, 9}이다.

 

이제 코드를 작성하여 결과를 비교해보자.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import java.util.Arrays;
 
public class test {
 
    public static void main(String[] args) {
        // 오름차순
        int[] array = { 1539710 };
        int tmp; // swap을 위한 변수 선언
        // cycle은 (배열의 크기-1)만큼 진행된다.
        for (int i = 0; i < array.length - 1; i++) {
            for (int j = 0; j < array.length - 1 - i; j++) {
                if (array[j] > array[j + 1]) {
                    tmp = array[j + 1];
                    array[j + 1= array[j];
                    array[j] = tmp;
                }
            }
        }
        System.out.println(Arrays.toString(array));
 
    }
 
}
 
cs

 

동일한 결과가 나타난다. 

 

내림차순으로 정렬하는 경우는 오름차순 정렬과 같은 논의이므로 부등호의 방향만 달리하면 된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import java.util.Arrays;
 
public class test {
 
    public static void main(String[] args) {
        // 내림차순
        int[] array = { 1539710 };
        int tmp; // swap을 위한 변수 선언
        // cycle은 (배열의 크기-1)만큼 진행된다.
        for (int i = 0; i < array.length - 1; i++) {
            for (int j = 0; j < array.length - 1 - i; j++) {
                if (array[j] < array[j + 1]) {
                    tmp = array[j + 1];
                    array[j + 1= array[j];
                    array[j] = tmp;
                }
            }
        }
        System.out.println(Arrays.toString(array));
 
    }
 
}
 
cs

 

결과는 { 9, 7, 5, 3, 1, 1, 0}.

Theme. 배열의 최댓값/최솟값 구하기

 

1. 최댓값

먼저, 배열 arr = {1, 5, 9, 3, 7, 1, 0}이 있다고 하자.

결론부터 말하면 배열의 첫번째 값을 최댓값이라고 가정하고, 이후 index마다의 값들과의 비교를 통해 더 큰 값이 존재하면 그 값을 최댓값으로 대입해주며 배열의 끝까지 비교해보는 것이다.

이제 자세히 알아보자.

int max = array[0];을 통해 배열의 첫번째 값을 max(최댓값)라고 가정해보자.

이제, 배열의 첫번째 값과 두번째 값을 비교해보자.

그 결과 array[1]인 5가 더 크므로 max의 값에 5를 대입해준다.(최댓값이 5인 상태)

같은 방식으로 한번더 진행한 결과는, 다음과 같다.

array[2]인 9가 5보다 크기 때문에 max의 값에 9를 대입해준다.(최댓값이 9인 상태)

이후 진행상황은, 

배열의 끝까지 비교한 결과 최댓값은 최종적으로 9가 된다.

이제 코드를 작성하여 결과를 확인해보자.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class test {
 
    public static void main(String[] args) {
        int[] array = { 1593710 }; // 배열 생성
        int max = array[0]; // 배열의 첫번째 값을 최댓값으로 가정
        for (int i = 0; i < array.length; i++) {
            if (max < array[i]) {
                max = array[i];
            }
        }
        System.out.println(max);
 
    }
 
}
 
cs

최댓값은 9가 나온다. 

 

2. 최솟값

최댓값을 구하는 방식과 같은 논의이나 단, 부등호의 방향이 바뀌는 것뿐이다. 

최댓값을 구할 때와 동일한 배열을 가지고 최솟값을 구하는 코드를 작성해보면,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class test {
 
    public static void main(String[] args) {
        int[] array = { 1593710 }; // 배열 생성
        int min = array[0]; // 배열의 첫번째 값을 최솟값으로 가정
        for (int i = 0; i < array.length; i++) {
            if (min > array[i]) {
                min = array[i];
            }
        }
        System.out.println(min);
 
    }
 
}
 
cs

최솟값은 0이 나온다.

 

Theme. SWEA 2068. 최대수 구하기

https://swexpertacademy.com/main/solvingProblem/solvingProblem.do

 

SW Expert Academy

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

swexpertacademy.com

< Solution >

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
import java.util.Scanner;
 
public class Solution {
 
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
 
        int T = sc.nextInt();
 
        for (int t = 1; t <= T; t++) {
            int[] arr = new int[10];
            for (int i = 0; i < 10; i++) {
                arr[i] = sc.nextInt();
            }
            int max = arr[0];
            for (int i = 0; i < arr.length; i++) {
                if (max < arr[i]) {
                    max = arr[i];
                }
            }
            System.out.println("#" + t + " " + max);
        }
 
    }
 
}
 
cs

 

 

+ Recent posts