21275번: 폰 호석만
https://www.acmicpc.net/problem/21275
# 코드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Main {
static String xA, xB, x, max; // xA와 xB는 입력받은 문자열, x는 결과 값, max는 최대 값
static long a, b; // a와 b는 진법을 나타냄
static int count; // 가능한 해의 개수
static int[] arr; // 각 문자의 값(0~9, a~z)을 저장하는 배열
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] s = br.readLine().split(" ");
xA = s[0]; // 첫 번째 수
xB = s[1]; // 두 번째 수
// x의 최대 값은 2^63 (long 타입이 저장할 수 있는 범위 내의 값)
max = String.valueOf(Math.pow(2, 63));
// arr 배열에 1~36진법에 해당하는 숫자 저장
arr = new int[200]; // 아스키코드에 맞춰 배열 크기 설정
for (int i = 0; i < 9; i++) {
// '1'~'9' 문자를 숫자 1~9로 저장
// arr[49~57] == 1~9
arr[i + '1'] = i + 1;
}
for (int i = 0; i < 26; i++) {
// 'a'~'z' 문자를 숫자 10~35로 저장
// arr[97~122] == a~z == 10~35
arr['a' + i] = i + 10;
}
solve();
if (count == 0) {
System.out.println("Impossible"); // 불가능한 경우
} else if (count == 1) {
String toInteger = x.substring(0, x.length() - 2); // 결과에서 소수점 제거
System.out.println(toInteger + " " + a + " " + b); // 결과와 진법 출력
} else {
System.out.println("Multiple"); // 가능한 경우가 여러 개인 경우
}
}
public static void solve() {
// i(=xA), j(=xB) 를 1~36 진법으로 순차적으로 체크
for (int i = 1; i <= 36; i++) {
for (int j = 1; j <= 36; j++) {
// A ≠ B 이므로 i와 j가 같으면 연산 패스
if (i == j) {
continue;
}
// 두 진법에서 유효한 값인지 체크하고 값이 같은지 확인
if (check(i, xA) && check(j, xB)) {
if (find(i, xA).equals(find(j, xB))) {
// 결과 값이 최대 값(2^63)을 넘으면 패스
if (find(i, xA).compareTo(max) >= 1) {
continue;
}
// 가능한 경우의 수를 증가시키고 결과 저장
count++;
x = find(i, xA);
a = i;
b = j;
}
}
}
}
}
// 주어진 진법에서 문자열을 숫자로 변환
public static String find(int a, String s) {
int temp = 0;
double result = 0;
// 문자열을 뒤에서부터 한 자리씩 계산
for (int i = s.length()-1; i >= 0; i--) {
int t = arr[s.charAt(i)]; // 각 문자의 값을 가져옴
result += Math.pow(a, temp) * t; // 해당 진법에 맞게 계산
temp++;
}
// 결과를 문자열로 반환
return String.valueOf(result);
}
// 주어진 진법에서 사용할 수 있는 문자인지 체크
public static boolean check(int a, String s) {
// 문자열의 각 문자가 해당 진법에서 유효한지 확인
for (int i = 0; i < s.length(); i++) {
// 만약 진법보다 큰 문자가 있으면 false 반환
if(a <= arr[s.charAt(i)]) {
return false;
}
}
return true;
}
}
- 자잘하게 챙겨야 하는 것이 많은 문제였다.
- 주의할 것은 체크하고 있는 진법보다 입력 받은 값이 크다면 모두 패스하고 find()를 실행하지 않아야 한다.
풀이는 아래 블로그를 참고했다.
백준 21275 [자바] java 폰 허석만
문제 링크: https://www.acmicpc.net/problem/21275 21275번: 폰 호석만 만약 문제의 조건에 맞는 X, A, B가 유일하게 존재한다면, X를 십진법으로 표현한 수와 A와 B를 공백으로 나누어 출력하라. 만약 만족하는
dingdingmin-back-end-developer.tistory.com
'코딩테스트 > 자바 문제풀이' 카테고리의 다른 글
[수학] 백준 22943 수 (0) | 2024.08.18 |
---|---|
[수학] 백준 1747 소수&팰린드롬 (0) | 2024.08.17 |
[수학] 백준 21919 소수 최소 공배수 (0) | 2024.08.15 |
[수학] 백준 2960 에라토스테네스의 체 (0) | 2024.08.14 |
[수학] 9613 GCD 합 (0) | 2024.08.13 |