다음과 같은 출력을 해야 하는 문제가 있다.
Sssss
sSsss
ssSss
sssSs
ssssS
sssSs
ssSss
sSsss
Sssss
어떻게 풀까?
직관적으로 떠오르는 규칙은 다음과 같다.
1) i == j
2) ( i + j ) % 8 == 0
이를 코드로 옮기면 다음과 같다.
public static void problem1(){
for (int i =0; i<9; i++){
for (int j = 0; j<5; j++){
if (i==j) {
System.out.print((char) ('s' -32));
continue;
}
if ((i+j) % 8 ==0){
System.out.print((char) ('s' -32));
continue;
}
System.out.print('s');
}
System.out.println();
}
}
9x5 행렬을 순회하면서, i==j 인 경우와 i+j의 합이 8인 경우 대문자를 출력하고, 그렇지 않은 경우 소문자를 출력한다.
그런데 이렇게 풀면 찜찜하다. 규칙을 자세히 보면 두 if문을 하나로 합칠 방법이 뭔가 있을 것 같기 때문이다.
대문자가 찍히는 시점은 언제일까? i와 j의 관계를 살펴보면 다음과 같다.
i = 0 -> j = 0
i = 1 -> j =1
i = 2 -> j =2
i = 3 -> j =3
i = 4 -> j =4
i = 5 -> j = 3
i = 6 -> j =2
i = 7 -> j = 1
i = 8 -> j =0
보면 i와 j가 순서대로 같이 증가하다가 5 시점부터 i는 증가하고 j는 감소한다.
이에 대한 수학적 규칙은 다음과 같다.
j = abs(4 - abs( (i % 8) - 4) )
규칙에 하나씩 대입해보자.
i = 0 -> j = abs ( 4 - 4) = 0
i = 1 -> j = abs( 4 - abs(1 - 4) ) = 1
i = 2 -> j = abs( 4 - abs(2- 4) ) = 2
i = 3 -> j = abs( 4 - abs(3-4) ) = 3
i = 4 -> j = abs( 4 - abs(4-4) ) = 4
i = 5 -> j = abs( 4 - abs(1-4) )= 3
i = 6 -> j = abs( 4 - abs(2-4) ) = 2
i = 7 -> j = abs( 4 - abs(3-4) ) = 1
i = 8 -> j = abs( 4 - abs(4-4) ) = 0
원하는 i와 j의 쌍을 이렇게 구했다.
다음은 이 규칙을 이용해 요구사항을 출력하는 코드이다.
public static void problem1_2() {
int n = 9;
int m = 5;
char[][] numbers = new char[n][m];
for (int i =0; i< n;i++){
for (int j = 0; j < m; j++){
numbers[i][j] = 's';
int k = Math.abs(n/2 - Math.abs((i % (n-1)) - n/2));
numbers[i][k]= 'S';
}
}
for(int i =0; i< n; i++){
for (int j =0; j<m; j++){
System.out.print(numbers[i][j]);
}
System.out.println();
}
}
i와 j에 대해 절대값과 나머지를 이용해 공식을 찾으면 쉽게 풀리는 문제들이 종종 있다. 하지만 이러한 수학 규칙을 찾는 것이 쉽지만은 않은 것 같다.
'알고리즘 > 기초' 카테고리의 다른 글
자바 숫자의 자릿수를 판별하는 5가지 방식 (1) | 2023.06.21 |
---|---|
자바 문자열 역순 뒤집기 4가지 방법 (1) | 2023.06.21 |
퀵 정렬 (Quick Sort) - 아이디어, 작동 원리, 성능 및 시간 복잡도, 특징, 자바 구현 코드 (0) | 2023.06.11 |
선택 정렬, 아이디어, 작동 원리, 자바 구현 코드 (0) | 2023.06.10 |
계수 정렬(countin/카운팅 정렬) 아이디어, 작동원리, 시간 복잡도, 자바 구현 코드 (0) | 2023.06.10 |