2022. 4. 18. 16:27ㆍ코딩 테스트(JAVA)/백준
https://www.acmicpc.net/problem/3460
문제
양의 정수 n이 주어졌을 때, 이를 이진수로 나타냈을 때 1의 위치를 모두 찾는 프로그램을 작성하시오. 최하위 비트(least significant bit, lsb)의 위치는 0이다.
입력
첫째 줄에 테스트 케이스의 개수 T가 주어진다. 각 테스트 케이스는 한 줄로 이루어져 있고, n이 주어진다. (1 ≤ T ≤ 10, 1 ≤ n ≤ 106)
출력
각 테스트 케이스에 대해서, 1의 위치를 공백으로 구분해서 줄 하나에 출력한다. 위치가 낮은 것부터 출력한다.
예제 입력 1 복사
1
13
예제 출력 1 복사
0 2 3
문제 분석
이번에는 문제가 쉬운 것 같아서 따로 문제 분석을 들어가지 않고 바로 코드 구현을 시작했습니다.
결과적으로.... 방향을 잘못잡아서 2시간 동안 헤매다가 문제를 다시 보니 제가 잘못된 방향으로 이해했다는 것을 깨달았습니다. 그 후 코드를 수정하니 한 번에 통과... 하였습니다.
챙겨야 할 여러 개념이 있었지만 무엇보다 문제 분석의 중요성을 다시 깨닫는 시간이었습니다.
바로 성공 코드를 보여드리는 것보단 실패 코드를 통해 어떤 식으로 문제 분석을 잘못하였는지 복기하는 시간을 가져보겠습니다.
만약 성공 코드가 바로 궁금하신 분들은 맨 밑으로 내려가시면 됩니다.^^
실패 코드
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner kb = new Scanner(System.in);
int t = kb.nextInt();
int n = kb.nextInt(); // 13
String binary = Integer.toBinaryString(n);
// System.out.println(binary); 1101
// String -> char배열
char[] ch = binary.toCharArray();
// System.out.println(Arrays.toString(ch)); [1, 1, 0, 1]
for(int i=0; i<ch.length; i++) { // [주의] char타입이므로 '1'
if(ch[i] == '1') System.out.print(i + " ");
}
}
}
// 출력
0 1 3
이 당시
1. 입력 예제에 입력을 2번 받는 것을 확인 후 코드 첫 부분에 t, n을 한 번에 받음 (아무 의심 없는 상태)
2. 10진수에서 2진수로 변환하는 방법 서칭 후 적용
Integer.toBinaryString(n)
3. 출력을 해보니 0 1 3 이 나와서
거꾸로 출력해야겠다는 생각에 선 작업으로 list에 넣어서 reverse메서드를 활용해야겠다고 판단 후 코드를 수정하였습니다.
바보야 그게 아니야...
실패 코드
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner kb = new Scanner(System.in);
int t = kb.nextInt();
int n = kb.nextInt(); // 13
String binary = Integer.toBinaryString(n);
char[] chArr = binary.toCharArray(); // [1, 1, 0, 1]
ArrayList<Character> chList = new ArrayList<>();
for(char ob : chArr) {
chList.add(ob);
}
Collections.reverse(chList); // [1, 0, 1, 1]
for(int i=0; i<chList.size(); i++) {
if(chList.get(i) == '1') System.out.print(i + " ");
}
}
}
// 출력
0 2 3
여기서,,, 이상한 것을 깨닫고 구글 서칭에 들어갔습니다.
문제 상 "첫째 줄에 테스트 케이스의 개수 T가 주어진다. 각 테스트 케이스는 한 줄로 이루어져 있고, n이 주어진다."
이렇게 간단하게 한 문장으로 쓰여있는데, 제 마음대로 이해하고 넘어갔다는 것을 알고....
코드를 처음부터 수정하였고, 다행히 바로 통과되었습니다.
문제 완벽히 이해하고 접근하기!
성공 코드
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc =new Scanner(System.in);
int t = sc.nextInt();
for(int i=0; i<t; i++) {
int n = sc.nextInt();
String Binary = Integer.toBinaryString(n);
for(int j=Binary.length()-1; j>=0; j--) {
if(Binary.charAt(j)=='1') { // 문자이므로 ''
System.out.print(Binary.length()-j-1+" ");
}
}
}
}
}
💡 [암기] for문 반대로 돌린 후 출력을 오른쪽 -> 왼쪽으로 하는 방법
Binary.length()-j-1
꼭 알고 있어야 할 10진수 ↔ 2진수, 8진수, 16진수 변환 방법은 다음 포스팅을 참고하시길 바랍니다.
'코딩 테스트(JAVA) > 백준' 카테고리의 다른 글
[백준 10870번] 피보나치 수 5 (0) | 2022.04.19 |
---|---|
[백준 2460번] 지능형 기차2 (0) | 2022.04.19 |
[백준 2501번] 약수 구하기 (0) | 2022.04.18 |
[백준 2217번] 로프 (0) | 2022.04.17 |
[백준 1316번] 그룹 단어 체커 (0) | 2022.04.17 |