2026.07.07
38.5/100
99와 같이 n = 9일 때, x = 90, y = 100과 같이
자릿수가 올라가는 경우를 고려하지 않음
class Solution {
public int solution(int storey) {
int result = 0;
int dividend = 1;
int digit = 0;
while(true) { // storey가 몇자리수인지 계산
if (storey / dividend == 0) {
break;
}
dividend *= 10;
digit++;
}
dividend = (int)Math.round(Math.pow(10, digit - 1));
while(true) {
int n = storey / dividend;
int x = n * dividend;
int y = (n + 1) * dividend;
if (storey - x > y - storey) {
storey = y - storey;
result = result + n + 1;
}
else {
storey = storey - x;
result = result + n;
}
dividend /= 10;
if (dividend == 1) {
result += storey;
break;
}
}
return result;
}
}
53.8/100
56의 경우 코드로 진행하게 되면 10이 나오는 반면,
실제 정답은 -100(1), 40(4), 4(4)로 9이다.
1의 자리 버튼을 10번 이상 누르게 되면 10의 자리에 영향을 줌
그 반대로 10의 자리를 아무리 눌러봤자 1의 자리에는 영향을 주지 않음
아래-위 관계인 것을 알 수 있으며,
상위 자리부터 판별하는 것이 아닌, 하위 자릿수부터 판별해야 함
class Solution {
public int solution(int storey) {
int result = 0;
int dividend = 1;
int digit = 0;
while(true) { // storey가 몇자리수인지 계산
if (storey / dividend == 0) {
break;
}
dividend *= 10;
digit++;
}
dividend = (int)Math.round(Math.pow(10, digit - 1));
while(true) {
int n = storey / dividend;
int x = n * dividend;
int y = (n + 1) * dividend;
if (storey - x > y - storey) {
storey = y - storey;
result = ((n + 1) < 10 ? (result + n + 1) : (result + 1));
}
else {
storey = storey - x;
result = result + n;
}
dividend /= 10;
if (dividend == 1) {
result += storey;
break;
}
}
return result;
}
}
46.2/100
최상단 자릿수를 고려하지 않고 그냥 더해버림
class Solution {
public int solution(int storey) {
int result = 0;
int dividend = 1;
int digit = 0;
while(true) { // storey가 몇자리수인지 계산
if (storey / dividend == 0) {
break;
}
dividend *= 10;
digit++;
}
dividend = (int)Math.round(Math.pow(10, digit - 1));
int[] digits = new int[digit];
for (int i = 0; i < digit; i++) {
digits[i] = storey / dividend;
storey = storey % dividend;
dividend /= 10;
}
for (int i = digit - 1; i >= 0; i--) {
if (digits[i] > 5 && i > 0) {
digits[i - 1] += 1;
result = result + 10 - digits[i];
}
else {
result = (digits[i] < 10 ? (result + digits[i]) : (result + 1));
}
}
return result;
}
}
76.9/100
현재 자릿값이 정확히 5일 때, 높은 자릿수가
class Solution {
public int solution(int storey) {
int result = 0;
int dividend = 1;
int digit = 0;
while(true) { // storey가 몇자리수인지 계산
if (storey / dividend == 0) {
break;
}
dividend *= 10;
digit++;
}
dividend = (int)Math.round(Math.pow(10, digit - 1));
int[] digits = new int[digit];
for (int i = 0; i < digit; i++) {
digits[i] = storey / dividend;
storey = storey % dividend;
dividend /= 10;
}
for (int i = digit - 1; i >= 0; i--) {
if (digits[i] > 5) {
if (i == 0) {
result = result + 10 - digits[i] + 1;
}
else {
digits[i - 1] += 1;
result = result + 10 - digits[i];
}
}
else {
result = result + digits[i];
}
}
return result;
}
}
84.6/100
연속적으로 5가 나오는 경우에 대한 경우
class Solution {
public int solution(int storey) {
int result = 0;
int dividend = 1;
int digit = 0;
while(true) { // storey가 몇자리수인지 계산
if (storey / dividend == 0) {
break;
}
dividend *= 10;
digit++;
}
dividend = (int)Math.round(Math.pow(10, digit - 1));
int[] digits = new int[digit];
for (int i = 0; i < digit; i++) {
digits[i] = storey / dividend;
storey = storey % dividend;
dividend /= 10;
}
for (int i = digit - 1; i >= 0; i--) {
if (digits[i] > 5) {
if (i == 0) {
result = result + 10 - digits[i] + 1;
}
else {
digits[i - 1] += 1;
result = result + 10 - digits[i];
}
}
else if (digits[i] == 5 && i != 0) {
if (digits[i - 1] > 5) {
digits[i - 1] += 1;
result = result + 10 - digits[i];
}
else {
result = result + digits[i];
}
}
else {
result = result + digits[i];
}
}
return result;
}
}
코드를 설계하는 과정과 구현은 스스로 했음
이후 실행 오류가 생기면 AI에게 어느 부분이 오류인지 물어보고,
해당 부분을 직접 구현하는 형태로 코드를 작성함
해당 코드는 DP를 이용해서 해결했는데,
DP란 큰 문제들을 작은 문제들로 쪼개고, 그 하위 문제의 답을 저장해뒀다가
재사용해서 문제를 해결하는 방식임
결국 많은 문제를 다양한 알고리즘으로 풀어가며
실력을 키워 나가는 과정은 처음 보는 알고리즘도 있을 것이고,
난해한 코드들도 정말 많을 것이다.
이 문제의 AI가 작성해 준 코드를 해석하는데만 해도 어려웠다.
정답률 50%대에 진입한 후로 점점 문제를 해결하기가 어려워지고 있지만,
자신감을 잃지 않고 모르는 문제는 답을 봐도 코드는 반드시 이해하고 간다는
마음가짐으로 임해야겠다.
class Solution {
public int solution(int storey) {
final int INF = Integer.MAX_VALUE / 2;
int noCarry = 0; // 자리올림 없이 여기까지 처리했을 때의 최소 비용
int withCarry = INF; // 자리올림을 받은 채로 여기까지 처리했을 때의 최소 비용 (1의 자리는 자리올림 받을 수 없으니 처음엔 불가능 상태)
while (storey > 0) {
int d = storey % 10;
storey /= 10;
int newNoCarry = noCarry + d; // 자리올림 없이 왔다가, 이번 자리도 내림
int newWithCarry = noCarry + (10 - d); // 자리올림 없이 왔다가, 이번 자리는 올림(다음 자리에 넘김)
if (withCarry < INF) {
int eff = d + 1; // 아래에서 자리올림을 받았다고 가정한 실질 값
if (eff < 10) {
newNoCarry = Math.min(newNoCarry, withCarry + eff);
newWithCarry = Math.min(newWithCarry, withCarry + (10 - eff));
} else { // d == 9 이면 eff == 10, 자리올림이 강제 확정되고 비용은 0
newWithCarry = Math.min(newWithCarry, withCarry);
}
}
noCarry = newNoCarry;
withCarry = newWithCarry;
}
return Math.min(noCarry, withCarry + 1); // 맨 끝에 자리올림이 남아있으면 새 자리 하나 값(1)을 더 지불
}
}