https://www.acmicpc.net/problem/1094
지민이는 길이가 64cm인 막대를 가지고 있다. 어느 날, 그는 길이가 Xcm인 막대가 가지고 싶어졌다. 지민이는 원래 가지고 있던 막대를 더 작은 막대로 자른다음에, 풀로 붙여서 길이가 Xcm인 막대를 만들려고 한다.
막대를 자르는 가장 쉬운 방법은 절반으로 자르는 것이다. 지민이는 아래와 같은 과정을 거쳐서 막대를 자르려고 한다.
- 지민이가 가지고 있는 막대의 길이를 모두 더한다. 처음에는 64cm 막대 하나만 가지고 있다. 이때, 합이 X보다 크다면, 아래와 같은 과정을 반복한다.
- 가지고 있는 막대 중 길이가 가장 짧은 것을 절반으로 자른다.
- 만약, 위에서 자른 막대의 절반 중 하나를 버리고 남아있는 막대의 길이의 합이 X보다 크거나 같다면, 위에서 자른 막대의 절반 중 하나를 버린다.
2.이제, 남아있는 모든 막대를 풀로 붙여서 Xcm를 만든다.X가 주어졌을 때, 위의 과정을 거친다면, 몇 개의 막대를 풀로 붙여서 Xcm를 만들 수 있는지 구하는 프로그램을 작성하시오.
- 구현하면 되는 문제 같다! 반씩 잘라가면서 넣고 뺴고 하면서 세면 되지 않을까?
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int X = Integer.parseInt(br.readLine()); // 막대기 길이
int answer = 0;
int start = 64;
while (X > 0) {
if (start > X) {
start /= 2;
} else {
X -= start;
answer++; //한개씩 추가
}
}
System.out.println(answer);
}
}
64부터 시작하고
/2를 지속적으로 한다는 것은 2진수로 표현 가능하다는 점 =비트마스킹활용해보기
package baekjoon;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int X = Integer.parseInt(br.readLine()); // 막대기 길이
int answer = 0;
// 64는 2의 6승, 1까지하면 7개의 칸이 필요하다
for (int i = 0; i < 7; i++) {
if ((X & (1 << i)) > 0)
//1씩 배열을 땡겨가면서 X의 비트가 1인지를 확인하겠다 (&)
answer++;
}
System.out.println(answer);
}
}
0과 1을 사용하여 데이터를 저장하고 연산할 수 있는 기법으로, 빠른 연산이 필요할 때 사용하는 알고리즘 입니다.

(출처: https://travelbeeee.tistory.com/451)
<<<< 해당 기호는 보통 '쉬프트'라고 부르며, 해당 자리를 한 칸씩 왼쪽으로 옮긴다는 뜻입니다. 오른쪽으로 옮기고 싶을 경우는 >> 이렇게 표현합니다.
a << b 일 경우, a를 b 만큼 이동한다고 생각하면 됩니다.
14 : 00001110
14 << 2 : 00111000
14 >> 2 : 00000011
자바에서는 1 << i 방식으로 사용해서 부분집합이나 XOR 연산을 통해 계산할 수 있습니다.
for (int i = 0; i < 7; i++) {
if ((X & (1 << i)) > 0)
//1씩 배열을 땡겨가면서 X의 비트가 1인지를 확인하겠다 (&)
answer++;
}
위 알고리즘에서는 해당 부분으로 확인할 수 있습니다. i번째 비트가 1임을 확인한다는 뜻으로 이해하면 저는 더 쉬웠습니다 :)
해당 부분에서는 & 연산자를 사용함으로써 둘의 부분이 같은지를 확인했습니다.