본문 바로가기

별걸다하는 IT/알고리즘 문제풀이

[백준 Baekjoon알고리즘] 1110번 더하기 사이클 문제 설명 및 오답 풀이

[백준 알고리즘 if문 단계 문제]

[1110] 더하기 사이클

문제

0보다 크거나 같고, 99보다 작거나 같은 정수가 주어질 때 다음과 같은 연산을 할 수 있다. 먼저 주어진 수가 10보다 작다면 앞에 0을 붙여 두 자리 수로 만들고, 각 자리의 숫자를 더한다. 그 다음, 주어진 수의 가장 오른쪽 자리 수와 앞에서 구한 합의 가장 오른쪽 자리 수를 이어 붙이면 새로운 수를 만들 수 있다. 다음 예를 보자.

26부터 시작한다. 2+6 = 8이다. 새로운 수는 68이다. 6+8 = 14이다. 새로운 수는 84이다. 8+4 = 12이다. 새로운 수는 42이다. 4+2 = 6이다. 새로운 수는 26이다.

위의 예는 4번만에 원래 수로 돌아올 수 있다. 따라서 26의 사이클의 길이는 4이다.

입출력

입력

첫째 줄에 N이 주어진다. N은 0보다 크거나 같고, 99보다 작거나 같은 정수이다.

출력

첫째 줄에 N의 사이클 길이를 출력한다

예제 입력

예제 출력

26

4

55

3

1

60

 

다 풀고 문제 확인하기~~

ANSWER

조심해야 할 것은 마지막 예시네요 하나의 정수가 들어올 경우 앞에 0을 붙여서 두 자리 숫자로 만들어야합니다.

혹시 시간초과 오류가 뜨거나 메모리 초과가 걸리는 분의 경우, 1,3 과 같은 한자리 숫자나 더했을 때 10이 넘어가는 (55, 68 등) 숫자를 넣어보고 예외처리가 잘 되어있는지 먼저 확인해보세요. :)

[1110 더하기 사이클 - JAVA 나눗셈, 모듈 연산]

오늘은 자바부터~!

가장 쉬운 방법은 10진수 특징을 이용하는 방법이겠죠??

10진수는 10이 기준이 되기 때문에 10으로 나눴을 때 몫은 십의자리로, 나머지는 일의자리로 배치됩니다.

예를 들어 26에서 일의 자리를 추출하려면 26 %10 해주면 됩니다. 그리고 추출한 일의 자리를 10의 자리로 옮기려면 다시 곱하기 10을 해주면 돼요. 10진수의 특징이죠! 16진수라면 십의 자리로 옮기기 위해 *16을 해줬겠죠?

import java.util.Scanner;
class Main{
   public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        int initNum = sc.nextInt();
        int num = initNum, count =0;
        while(initNum != num || count == 0){
            num = (num % 10) %10 + (num/10 + num%10)%10;
            count++;
        }
        System.out.println(count);
   }
}

요 코드 중에 (num%10)이 이전 숫자의 일의 자리수 이고

num/10+num%10 -> 부분이 일의 자리수 더하기 십의 자리수 입니다. 근데 이 부문이 6+8의 경우처럼 10이 넘어갈 수 있으니 또 모듈 계산을 한 번 더 수행해줘야 해요! 이거 빼먹어서 오류난 분들도 있을 거예요 ~ 

 

[1110 더하기 사이클 - C++ 나눗셈, 모듈 연산]

똑같은 로직을 C언어를 사용해볼게요. 그래도 완전 똑같으면 조큼 그러니까 변수를 좀 사용해서 가독성을 높여봤어요 ㅎㅎ

#include <iostream>
using namespace std;
int main()
{
	int initNum, num, count=0;
	int tens, units;
	cin >> initNum;
	tens = initNum / 10; //십의 자리
	units = initNum % 10; //일의 자리
	do {
		num = units * 10 + (tens + units) % 10;
		tens = num / 10; 
		units = num % 10;
		count++;
	} while (initNum != num);
	cout << count << endl;
	return 0;
}

[1110 더하기 사이클 - C++ 문자열 비교]

이번에는 초큼 (?) 다른 풀이를 살펴볼까요

위 알고리즘보다 나은 풀이는 아니지만 이런 방법도 있구나 생각하는 것은 좋으니까요

위에 선보였던 풀이는 숫자를 받아서 그 숫자를 조작함으로써 결과를 얻어낸건데

이번 풀이는 각각 숫자로 받지 않고 문자열 배열에 받아서 십의자리는 십의자리수끼리 비교하고 일의자리수끼리 비교해보는 거예요.

#include <iostream>
#include <string>
using namespace std;

int main()
{
	string initNum;
	int initTens, initUnits, sum, count = 0;
	getline(cin, initNum);
	if (initNum.length() == 1) {
		initTens = 0;
		initUnits = initNum[0] - '0';
	}
	else {
		initTens = initNum[0] - '0';
		initUnits = initNum[1] - '0';
	}
	int tens = initTens;
	int units = initUnits;
	do {
		sum = tens + units;
		tens = units;
		units = sum % 10;
		count++;
	} while (!(initTens == tens && initUnits == units));
	cout << count;
	return 0;
}

문자 -'0' = 숫자

라는 아스키코드의 특징을 이용했어요

 

[1110 더하기 사이클 - JAVA 문자열 비교]

같은 코드지만 Java 버전! 어차피 String으로 읽어들일꺼 좀 더 빠른 BufferedReader로 읽어봤어요

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
public class Main{
	static int initTens, initUnits, sum, count=0;
    public static void main(String[] args) throws IOException{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String input = br.readLine();
        if(input.length()<2) {
        	input ="0"+input;
        }
        int tens = initTens = Integer.parseInt(input.substring(0, 1));
        int units = initUnits = Integer.parseInt(input.substring(1, 2));
        
        do {
        	sum = tens+units;
        	tens = units;
        	units = sum%10;
        	count++;
        }while(!(initTens == tens && initUnits == units));
        System.out.println(count);
    }
}

제가 푼 알고리즘들은 생각에서 나온 하나의 예시일뿐이지 차선책은 아닙니다 더 좋은 풀이 있으면 공유해주세요 :)

도움이 됐다면 공감/ 댓글/ 광고클릭으로 보답은 어떤가요?

다음 포스팅에서 또 더 질좋은 컨텐츠로 봬용~~ ㅎㅎ