7개의 LED로 구성된 세븐 세그먼트로 숫자가 표시된다.
반전 가능한 LED 수가 제한되어있기 때문에 숫자가 변할 때 필요한 LED 수를 계산해야한다.
예를 들어, 0에서 1로는 4개의 LED가 반전되어야한다.
숫자가 0~9로 제한되어있기 때문에 반전에 필요한 LED 수를 직접 셀 수도 있지만, 인간 오류의 가능성과 시간적 효율이 좋지 않다.
따라서 숫자를 바이너리로 표현한 다음에 변경에 필요한 LED 수를 연산하는 것이 효율적이며, 오류의 가능성도 적다.
이렇게 각 LED 세그먼트를 0~6번으로 표현했을 때, 0 같은 경우 바이너리로 왼쪽부터 0번 LED로 시작해 0x1110111로 표현할 수 있다.
그리고 각 숫자끼리 XOR 연산을 해서 변경되어야하는 비트만 1로 표시되면 XOR 후 켜진 비트의 개수 = 변경해야할 비트의 수가 된다.
층수의 수가 많지 않고, O(N)로 연산되기 때문에 시작 층으로부터 해당 층으로 변경할 때 필요한 LED 수를 제한된 수와 비교해서 개수를 세어주면 된다.
import java.util.*;
import java.io.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
input(in);
solve();
}
static int height;
static int digit;
static int limit;
static int floor;
static int[][] cost;
static int[] num = {
0b1110111, // 0
0b0010010, // 1
0b1011101, // 2
0b1011011, // 3
0b0111010, // 4
0b1101011, // 5
0b1101111, // 6
0b1010010, // 7
0b1111111, // 8
0b1111011, // 9
};
static void input(BufferedReader in) throws IOException {
StringTokenizer tokens = new StringTokenizer(in.readLine());
height = Integer.parseInt(tokens.nextToken());
digit = Integer.parseInt(tokens.nextToken());
limit = Integer.parseInt(tokens.nextToken());
floor = Integer.parseInt(tokens.nextToken());
cost = new int[10][10];
// 각 숫자끼리 변경에 필요한 LED 수 미리 계산
for(int i = 0; i < 10; i++) {
for(int j = 0; j < 10; j++) {
int from = num[i];
int to = num[j];
int diff = Integer.bitCount(from ^ to);
cost[i][j] = diff;
}
}
}
static void solve() {
int cnt = 0;
for(int i = 1; i <= height; i++) {
if(floor != i && countRequiredLED(floor, i) <= limit) cnt++;
}
System.out.println(cnt);
}
static int countRequiredLED(int from, int to) {
int sum = 0;
for(int i = 0; i < digit; i++) {
int digitFrom = from % 10;
int digitTo = to % 10;
sum += cost[digitFrom][digitTo];
from /= 10;
to /= 10;
}
return sum;
}
}