11import java .util .*;
2+
23class Solution {
3- /**
4- 1 ~ 32,000
5- 1
6- 2 - 11
7- 3 - 21 12
8- 4 - 31 13 22
9- 5 - 14 41 23 32
10- 6 - 15 51 24 42 33
11- ...
12- **/
13- public int solution (int n , int number ) {
14- Set [] sets = new Set [9 ];
15- for (int i =1 ; i <9 ; i ++) {
16- sets [i ] = new HashSet <Integer >();
17- }
18- sets [1 ].add (n );
19-
20- for (int i =2 ; i <9 ; i ++) {
21- for (int j =1 ; j <i ; j ++) {
22- Set <Integer > pre = sets [j ];
23- Set <Integer > post = sets [i -j ];
24-
25- for (Integer preNum : pre ) {
26- for (Integer postNum : post ) {
27- sets [i ].add (preNum + postNum );
28- sets [i ].add (preNum - postNum );
29- sets [i ].add (preNum * postNum );
30- if (postNum != 0 && preNum != 0 ) {
31- sets [i ].add (preNum / postNum );
32- }
33- }
34- }
4+ private int N ;
5+ private int number ;
6+ private Map <Integer , Set <Integer >> memo = new HashMap <>();
7+
8+ public int solution (int iN , int iNumber ) {
9+ this .N = iN ;
10+ this .number = iNumber ;
11+
12+ if (N == number ) return 1 ;
13+
14+ // 1개부터 8개까지 탑다운으로 계산
15+ for (int cnt = 1 ; cnt <= 8 ; cnt ++) {
16+ Set <Integer > candidates = recur (cnt );
17+ if (candidates .contains (number )) {
18+ return cnt ;
3519 }
36- sets [i ].add (Integer .parseInt (String .valueOf (n ).repeat (i )));
3720 }
38- for (int i =1 ; i <9 ; i ++) {
39- Set <Integer > set = sets [i ];
40- for (Integer num : set ) {
41- if (num == number ) {
42- return i ;
21+ return -1 ;
22+ }
23+
24+ // recur(cnt): N을 cnt번 사용해서 만들 수 있는 모든 값
25+ private Set <Integer > recur (int cnt ) {
26+ if (memo .containsKey (cnt )) {
27+ return memo .get (cnt );
28+ }
29+
30+ Set <Integer > result = new HashSet <>();
31+
32+ // 1) 이어붙인 수 추가 (5, 55, 555 ...)
33+ int repeated = 0 ;
34+ for (int i = 0 ; i < cnt ; i ++) {
35+ repeated = repeated * 10 + N ;
36+ }
37+ result .add (repeated );
38+
39+ // 2) cnt를 (left + right)로 분할해서 조합
40+ for (int left = 1 ; left < cnt ; left ++) {
41+ int right = cnt - left ;
42+
43+ Set <Integer > leftSet = recur (left );
44+ Set <Integer > rightSet = recur (right );
45+
46+ for (int a : leftSet ) {
47+ for (int b : rightSet ) {
48+ result .add (a + b );
49+ result .add (a - b );
50+ result .add (a * b );
51+ if (b != 0 ) {
52+ result .add (a / b ); // 정수 나눗셈
53+ }
4354 }
4455 }
4556 }
46-
47- return -1 ;
57+
58+ memo .put (cnt , result );
59+ return result ;
4860 }
4961}
0 commit comments