10610번: 30

이정석·2023년 10월 19일

10610번: 30

문제링크: 10610번: 30

문제

어느 날, 미르코는 우연히 길거리에서 양수 N을 보았다. 미르코는 30이란 수를 존경하기 때문에, 그는 길거리에서 찾은 수에 포함된 숫자들을 섞어 30의 배수가 되는 가장 큰 수를 만들고 싶어한다.

미르코를 도와 그가 만들고 싶어하는 수를 계산하는 프로그램을 작성하라.

입력

N을 입력받는다. N는 최대 105개의 숫자로 구성되어 있으며, 0으로 시작하지 않는다.

출력

미르코가 만들고 싶어하는 수가 존재한다면 그 수를 출력하라. 그 수가 존재하지 않는다면, -1을 출력하라.

설명

'숫자를 입력받아 각 숫자를 재배열해서 30의 배수를 만들 수 있는가?'를 묻는 문제인데 여기서 중요한 점은 '30의 배수'이다.

30의 배수라는 것은 곧 3의 배수이자 10의 배수인 수를 만들라는 것이다.

  1. 10의 배수는 숫자중에 0이 있는지를 확인하면 된다.
  2. 3의 배수는 각 자리의 숫자의 합이 3의배수인지를 확인하면 된다.

각 자리수의 합이 3의 배수이면 그 숫자가 3의배수인 것은 수학적으로 증명된 사실이다. 2,3,4,5,8,16등 여러 숫자에 대해서 배수를 검사하는 방법이 존재한다.

위 두가지 사실을 이용하기 위해 다음과 같은 방법으로 숫자를 구했다.

  1. 문자열로 입력받고 오름차순으로 정렬한다.
  2. 제일작은숫자(0번 인덱스)가 0인지 확인한다.
  3. 1번 인덱스의 숫자부터 끝까지 각 자리 합이 3의 배수인지 확인한다.
  4. 3의 배수라면 정렬한 값을 뒤집어서 출력한다.

코드

#include <iostream>
#include <string>
#include <algorithm>
#include <cstdlib>
#define endl '\n'

using namespace std;

void solve() {
	string s;
	cin >> s;
	sort(s.begin(), s.end());

	if (s[0] != '0') {
		cout << -1;
		return;
	}

	int total = 0;
	for (int i = 1; i < s.size(); ++i) {
		total += s[i] - '0';
	}

	if (total % 3 != 0) {
		cout << -1;
		return;
	}
	reverse(s.begin(), s.end());
	cout << s;
}

int main() {
	ios_base::sync_with_stdio(0);
	cin.tie(NULL); cout.tie(NULL);
	//freopen("input.txt", "r", stdin);
	solve();
	return 0;
}
profile
게임 개발자가 되고 싶은 한 소?년

0개의 댓글