본문 바로가기

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

[COCI 2009/2010기출, 백준 알고리즘] FILIP, 2908번 상수 문제 해설 및 문제 풀이(C/C++/자바)

안녕하세요! ㅎㅎ 오늘도 시작하는 알고리즘 풀이입니다.

고럼 문제를 볼까요?


출처: COCI 2009/2010년도 1번 문항 FILIP

출처: 백준 2908번 (번역본)

난이도: 하

분류: 문자열 사용하기

 

기출문제 사진

백준 사이트에서는 상수라는 제목으로 올라와 있는 문제입니다! 정답률이 매우 높아요 ㅎㅎ

 

정답 비율: 69.8%

[2908번] 상수

여기서 문제 이름 상수는 숫자가 아니라 동생 이름이라는거..ㅎㅎㅎ 실제 문제에서도 동생이름이 FILIP인데 문제 이름이 FILIP이예요 ㅎㅎ

문제

상근이의 동생 상수는 수학을 정말 못한다. 상수는 숫자를 읽는데 문제가 있다. 이렇게 수학을 못하는 상수를 위해서 상근이는 수의 크기를 비교하는 문제를 내주었다. 상근이는 세 자리 수 두 개를 칠판에 써주었다. 그 다ㅡㅇㅁ에 크기가 큰 수를 말해보라고 했다. 

상수는 수를 다른 사람과 다르게 거꾸로 읽는다. 예를 들어, 734와 893을 칠판에 적었다면, 상수는 이 수를 437과 398로 읽는다. 따라서 상수는 두 수 중 큰 수인 437을 큰 수라고 말할 것이다.

두 수가 주어졌을 때, 상수의 대답을 출력하는 프로그램을 작성하시오.

입출력

입력: 첫째 줄에 상근이가 칠판에 적은 두 수 A와 B가 주어진다. 두 수는 같지 않은 세 자리 수 이며, 0이 포함되어 있지 않다.

출력: 첫째 줄에 상수의 대답을 출력한다.


같이 풀어봐요 !!

밑에 내려가면 정답 코드와 해설 있어요~!!


ANSWER

문제를 한 마디로 요약하면 수를 반전한뒤 비교하라는 말이군요 ㅎㅎ

어차피 비교하는게 두 수밖에 없으니까 굳이 반전시킨 수를 저장할 필요 없이 나눗셈과 모듈만으로 끝낼 수 있을 것 같은데... 여러분들은 가장 먼저 생각난 풀이 방법이 어떤건가요?

 

JAVA 언어 코드

[상수 문제 JAVA 언어 풀이 - 나머지와 모듈 ]

저번 시간에 C언어로 먼저 한 것 같으니까 자바로 조건문과 모듈연산을 통해 풀어볼게요

import java.io.IOException;
import java.util.Scanner;
public class Main {
	public static int a, b;
	public static void main(String[] args) throws IOException {
		Scanner sc = new Scanner(System.in);
		a = sc.nextInt(); b=sc.nextInt();
		compareNum(a,b);
	}
	public static void compareNum(int a, int b) {
		do { 
			if(a%10>b%10) {printReverse(a); break;}
			else if (a%10<b%10) {printReverse(b); break;}
			else { //same
				System.out.print(a%10);
			}
			a/=10; b/=10;
		}while(a!=0); //어차피 a,b자리수는 동일
	}
	public static void printReverse(int a) {
		do {
			System.out.print(a%10);
			a/=10;
		}while(a!=0);
	}
}

메모리: 14264KB

시간: 104ms

코드길이: 596B

어차피 입력이 두 개밖에 안되니까 스캐너로 받아줬어요 ㅎㅎ

자리수가 3자리 이상인 미지수라면 이렇게 푸는게 좋겠지만 문제의 조건에 자리수가 3자리로 동일하다고 나와있어요. 배열을 사용하는게 비교도 직관적이고 속도도 빠르겠죠? 다음 문제는 배열을 활용해서 풀어볼게요 

 

[상수 문제 JAVA 언어 풀이 - 배열과 아스키코드]

알파벳을 0~26에 매칭시키고 싶다면 아스키코트 특징상 해당 문자 -'A'하면 되고

실제 인풋으로 들어오는 문자열 형태의 숫자를 진짜 0~ 이렇게 숫자에 매칭시키고 싶다면 숫자-'0'하면 되는 특징을 이용한 풀이예요

import java.io.IOException;
public class Main {
	public static void main(String[] args) throws IOException {
		int[] a = new int[3];
		int[] b = new int[3];
		for (int i = 0; i < a.length; i++) {
			a[i] = System.in.read()-'0';
		}
		System.in.read(); //공백제거
		for (int i = 0; i < b.length; i++) {
			b[i] = System.in.read()-'0';
		}
		int a_rvs = a[0]+a[1]*10+a[2]*100;
		int b_rvs = b[0]+b[1]*10+b[2]*100;
		System.out.println(a_rvs > b_rvs? a_rvs : b_rvs);
	}
}

앞에서 언급했다시피 3자리수밖에 안되므로 배열을 사용했어요. ㅎㅎ

요구되는 지식도 적고 문제도 단순해서 처음 프로그래밍 연습하는 사람이 풀어보기 좋은 문제인 것같아요.

 

C/C++ 언어 코드

[상수 문제 C++ 언어 풀이 - 나눗셈과 모듈]

처음 자바 코드와 똑같은 로직으로 푼거예요 ㅎㅎ 하지만 너무 똑같으면 좀 그르니까 do while대신 for문으로 바꿔준 정도의 미세한 차이..?

#include <iostream>
using namespace std;
void printReverse(int num) {
	do {
		cout << num % 10;
	} while ((num /= 10) != 0);
}
int main() {
	int a, b;
	cin >> a >> b;

	for (int a_val, b_val; a != 0; a /= 10, b /= 10) {
		a_val = a % 10; b_val = b % 10;
		if (a_val > b_val) {
			printReverse(a); break;
		}
		else if (a_val < b_val) {
			printReverse(b); break;
		}
		else cout << a_val;
	}
	return 0;
}

메모리: 1988KB

시간: 0ms

코드 길이: 404B

 

[상수 문제 C언어 풀이 ]

이번에는 그냥 수를 입력받자마자 거꾸로 뒤집은 후 그대로 비교해주는 코드예요. C언어로 풀어볼게요 ㅎㅎ 

#include <stdio.h>
int main() {
	int a,b, a_reverse=0, b_reverse=0;
	scanf("%d %d", &a, &b);
	a_reverse = (a % 10) * 100 + (a / 10) % 10 * 10 + (a / 100) % 10;
	b_reverse = (b % 10) * 100 + (b / 10) % 10 * 10 + (b / 100) % 10;
	printf("%d", a_reverse > b_reverse ? a_reverse: b_reverse);
	return 0;
}

메모리: 1116KB

시간: 0ms

코드길이: 301B

단순무식(?)하지만 빠르고 간단한 방법이죠 ㅎㅎ 어차피 인풋 숫자가 3자리 수밖에 안된다는 점을 이용한거예요 

 

[atoi 활용 풀이]

내 방식과 다른 풀이가 있길래 가져와봤어요 ㅎㅎ

문자 배열로 받은 다음에 각 자리수를 체인지 해줬네요ㅎㅎ 그리고 atoi를 사용해서 문자열을 정수로 변환해줬어요  

오늘 풀이는 여기까지 할게요! 여러분들은 어떤 방식으로 풀으셨나요?!

도움이 됐다면 공감& 댓글& 광고보답 감사합니다. 더 질 좋은 풀이로 찾아올게요! 다음 포스팅에서 봬요~!!