whileTrue: if count == n: print(name-1) break else: check = 0 for i in str(name): if i == "6": check += 1 if check == 3: count += 1 continue else: pass else: check = 0 name += 1
Go도 같은 방식의 풀이지만, string을 for문에 돌릴때 반환되는 값은 포인터 값이므로 string(x) 로 바꿔주는것만 주의 참조
string을 int로 바꿀때 strconv.ParseInt 를 사용했으나 strconv.Atoi를 사용해도됨
for i := 1; i < n; i++ { sum := i for _, j := range strconv.Itoa(sum) { k, _ := strconv.ParseInt(string(j), 10, 8) sum += int(k) } if sum == n { fmt.Printf("%d", i) break } elseif i == n-1 { fmt.Printf("%d", 0) } } }
몇개의 예를 들어 적어놓고 보니 계차수열의 형태를 나타낸다고 생각했다. 하지만 층수가 높아질수록 계차수열에 계차수열이 더해지는 형태로 나타났고 이를 점화식으로 나타내는것은 무리가 따랐다. 따라서, 문제에서 요구하는 층수와 호실수가 많지 않았으므로 전체에 대한 계산 결과를 저장하기로 결정했다.
1 2 3 4 5 6 7 8 9
li = [[0]*14for i in range(15)]
for i in range(1,15): li[0][i-1] = i li[i][0] = 1
for i in range(1,15): for j in range(1,14): li[i][j] = li[i-1][j] + li[i][j-1]
0층을 포함한 총 15층의 데이터를 저장하고 테스트 케이스로 입력받은 내용을 나타내는것으로 마무리했다.
1.거리에 따른 이동 규칙을 찾는 문제였다. 마지막 거리1을 제외한 나머지 거리를 역으로 탐색하는 방법을 생각했지만 규칙성을 찾아서 해결하는 문제에 옳지 못한 방법이었다. 타 게시판에서 힌트를 찾을 수 있었는데, 일정 거리를 지속적으로 늘려가다가 결국 마지막 1광년을 가기 위해 어느 시점부터 다시 지속적으로 움직이는 거리를 줄여야 한다는것이다.
2.그렇다면 어느 시점부터 다시 움직이는 거리를 줄이는 것일까? 이에 대한 해답은 총 이동거리에 따라서 어떻게 움직여야하는지 표를 그려 파악할 수 있었다.
거리
이동경로
움직인 횟수
1
1
1
2
1 1
2
3
1 1 1
3
4
1 2 1
3
5
1 2 1 1
4
6
1 2 2 1
4
7
1 2 2 1 1
5
8
1 2 2 2 1
5
9
1 2 3 2 1
5
10
1 2 3 2 1 1
6
11
1 2 3 2 2 1
6
12
1 2 3 3 2 1
6
13
1 2 3 3 2 1 1
7
14
1 2 3 3 2 2 1
7
15
1 2 3 3 3 2 1
7
16
1 2 3 4 3 2 1
7
17
1 2 3 4 3 2 1 1
8
18
1 2 3 4 3 2 2 1
8
19
1 2 3 4 3 3 2 1
8
20
1 2 3 4 3 3 2 1
8
21
1 2 3 4 4 3 2 1 1
9
3.위의 표를 살펴보면 제곱수가 되는 K(볼드체가 표시되어 있는 2,3,4….) 를 기준으로 움직인 회수가 바뀌는것을 확인할 수 있다. 다시말해, 우리가 움직여야하는 거리가 주어졌을 때 가장 가까운 제곱수로 나타낼 수 있는 값 K를 찾아야한다.
1 2 3 4 5
x, y = map(int, input().split()) stand = 0 if math.sqrt(y-x) - math.floor(math.sqrt(y-x)) < 0.5: stand = math.floor(math.sqrt(y-x)) else: stand = math.ceil(math.sqrt(y-x))
총 움직여야하는 거리 y-x 에 대해 sqrt값과 sqrt의 floor값 차이를 구해 이 값이 0.5 보다 작다면 기준이 되는 K값(위의 코드에서는 stand값)은 sqrt의 floor값이라고 할 수 있다. 반대로, 0.5보다 크다면 K값은 sqrt의 ceil값이 될 것이다.
4.기준이 되는 값 K를 구했다면 K와 움직인 횟수와의 관계를 살펴봐야 한다. 우리가 움직인 거리와 K의 제곱값을 비교하면 알 수 있다. 만약, y-x가 K의 제곱보다 크다면 움직인 횟수는 K2이며 y-x가 k의 제곱보다 작거나 같다면 움직인 횟수는 k2-1의 규칙을 따르는 것을 확인할 수 있다.
1 2 3 4
if y-x > stand**2: print(stand*2) elif y-x <= stand**2: print(stand*2-1)