2020. 9. 1. 23:05ㆍ알고리즘/Baekjoon
# 함수 # 브루트포스 알고리즘
내가 약한 부분을 알게 됐다. 브루트 알고리즘 처럼 로직 구현 과정이 한 스쿱으로 끝나지 않고 겉만 햝기 쉬운 문제. 걸린 시간 중 50%는 등차수열을 이해못해서 허비했다. 공차(수열들의 차이)가 0, 음수(-)도 허용되고 연속된 수가 동일한 수의 차이로 존재해야 하는 수열임..
문제를 간략 요약하자면 입력된 N까지 각 자릿 수가 등차수열로 이루어진 한수의 개수를 출력하면 된다. 예제 입출력을 보면 1 ~ 9 까지는 논외이기 때문에 자동 포함시켜 준 것 같고, 10~99까지는 모든 수가 1, 0 -n(-9<= n <= -1) 의 공차로 이루어진 한수가 맞기 때문에 1~99까지의 수는 자동으로 한수에 count 시켜줬다.
1) 시간 지체된 부분
오래 걸린 부분은 1) 입력을 한 번 받지만 반복문은 N번 돌려야 하고, 자릿 수를 쪼개는 과정과 2) 자릿 수끼리 뺀 값을 저장한 변수끼리 비교하는 로직을 찾는데 오래걸렸다. + 반복문이 끝나면 cnt 변수 ++ 와 배열, 뺀 값 저장하는 변수 null 과 0으로 초기화 하는 과정이 정리가 되어 있지 않는 방에서 입을 옷 찾는 것처럼 됐다.
2) 헷갈린 부분
숫자를 자릿 수로 쪼개야 할 때 while 과(n % 10)을 이용하면 int 타입으로 배열에 담을 수 있다는 것을 알았다. 하지만 for문 내에 제어변수 i를 또다시 while로 받으면 f**k 났기 때문에 String, split을 사용했다. 그래서 코드가 더럽게 깔끔하지 못한 부분이 있다. 코드가 깔끔하지 않으면 직관적으로 흐름이 잡히지 않아 출력 오류가 생겼을 때 대응이 더뎌진다. 지금은 힘들지만 조금씩 간결하게 만들자. 다른 분들 블로그를 보니까 for문 i를 while문 돌리기 위한 임시 변수를 만들어 사용했다. 아직 마이(많이) 부족하다. 항상 인지하자. 난 많이 부족하다. 그럼 어떻게 해야되나? 징징댈 시간에 조금 더 밀어붙여야 한다.
while을 사용하면 Array 쓰기가 어렵다. size를 가늠할 수 없기 때문인데 이 또한 size를 int 변수로 지정해 while문 돌때마다 ++ 해줘서 사이즈를 반복문이 도는 만큼만 추가추가(++) 하는 방법이 있다. 똑똑한 사람들은 정말 많다. 난 아님
for (int i = n; i > 0; i--) {
int k = 0;
int[] arr = new int[k];
if (i >= 100) {
tempNum = i;
while (tempNum > 0) {
arr[k]= (tempNum % 10);
tempNum /= 10;
k++;
}
}
3) 코드
앞서 숫자 쪼개는 방법 설명하느라 등차수열 확인하는 코드 로직 설명은 간략하게 할 수 밖에 없다. 아침 먹고 잠을 3시간이나 잤는데 왜 또 피곤할까. 조건식은 직관성을 위해 뒷자리에서 앞자리로 연결되도록 설정했고, 앞서 뺀 값을 현재 뺀 값과 비교하도록 변수를 두 개 설정했다. minus & minusEx. 우여곡절 끝에 탄생한 코드. 개발자가 되면 습관이 중요할 것 같은데, 지금 알고리즘 풀 땐 왜? Why? 라는 생각보단 정답 맞추는 데에 급급한다. 힘들지만 왜 for문 제어변수를 intList.size() -1 로 해줘야 하는지, 코드 효율화 할 수 있는 방법이 있는 지 로직을 세움에 있어 결정한 이유에 대해 1초만 더 생각하자.
package baekJoon.week6;
/*
어떤 자연수 X의 각 자리가 등차수열을 이루면 그 수를 한 수라고 한다. N이 주어졌을 때, 1보다 크거나 같고 N보다 작거나 같은 한수의 개수를
출력하는 프로그램 만들어라 ** 등차수열은 각 자리 수의 차이가 일정한 수열을 말한다. (123, 135)
- 입력: 첫째 줄에 1000보다 작거나 같은 자연수 N이 주어진다.
- 출력: 첫째 줄에 1보다 작거나 같은 한수의 개수를 출력한다.
*/
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class HanSu_1065_ex {
static int N;
static List<Integer> intList;
static int minus;
static int minusEx = Integer.MIN_VALUE;
static int cnt = 0;
static int tempNum;
static boolean flag = false;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
N = sc.nextInt();
System.out.println(han(N));
}
public static int han(int n) {
for (int i = n; i > 0; i--) {
intList = new ArrayList<>();
if (i >= 100) {
tempNum = i;
while (tempNum > 0) {
intList.add(tempNum % 10);
tempNum /= 10;
}
for (int k = 0; k < intList.size() - 1; k++) {
minus = intList.get(k) - intList.get(k + 1);
if (minus == minusEx) {
flag = true;
} else {
flag = false;
}
minusEx = minus;
}
if (flag == true) {
cnt++;
}
flag = false;
minusEx = Integer.MIN_VALUE;
minus = 0;
} else if (i < 100) {
cnt++;
}
}
return cnt;
}
}
'알고리즘 > Baekjoon' 카테고리의 다른 글
[백준] 1316 - 그룹 단어 체커 (0) | 2020.09.09 |
---|---|
[백준] 11654 - 아스키 코드 변환 (0) | 2020.09.02 |
[백준] 11399 - ATM (0) | 2020.08.26 |
[백준] 1003 - 피보나치 함수(재도전) (0) | 2020.08.26 |
[백준] 1758- 알바생 강호 (0) | 2020.08.26 |