백준 3052번 자바 - 서로 다른 나머지의 개수

황찬호·2021년 5월 20일
2

백준

목록 보기
1/1
post-thumbnail

문제

https://www.acmicpc.net/problem/3052

자바공부를 독학으로 시작한지 두달 쯤 됐다. 이 문제를 풀려고 2시간 정도 고민했지만 오류가 나고 해결할 방법을 모르겠어서 검색을 했다.(모르는 문제를 끝까지 풀려하는 자세는 좋지만 너무 오랫동안 붙잡고 있으면 안좋다고 한다. 한두시간 고민하고 안풀리면 검색을 해보자.)

Collection의 HashSet이라는 기능을 찾았지만, 나는 지금까지 내가 배워왔던 내용들을 기반(if문과 for문, 배열)으로 풀고 싶어서 일단 넘어갔다.
그리고 다른 방식을 찾았다. 내가 원하는 방식과 유사해서 나의 코드로 바꾸어 보았다.

1번과 2번은 내가 알고있는 방식, 그리고 3번은 HashSet을 이용한 방식이다. 3번은 무슨뜻인지 모르지만 나중에 보기 위해 남겨두겠다.

알고리즘 설명은 코드부분에 써놓았으니 그걸로 봐주었으면 좋겠다.

- 방법 1

Scanner를 이용하여 풀기

import java.util.Scanner;

public class Main {
	public static void main(String[] args) {

		Scanner sc = new Scanner(System.in);

		int[] arr = new int[10];
		boolean bl; //n번째와 n+1번째랑 비교하기 위한 변수
		int cnt = 0; //서로 다른 나머지들의 개수를 측정하기 위한 변수

		for(int i=0; i<arr.length; i++ ) {
			arr[i] = sc.nextInt() % 42;
		}
		for(int i=0; i<arr.length; i++ ) {
			bl = false; //기본값을 false로 설정
			for(int k=i+1; k<arr.length; k++ ) {
				if( arr[i] == arr[k] ) { //배열의 n번째와 n+1번째의 값을 비교
					bl = true; //같다면 bl값을 true로 변경
					break; //한번만 비교하면 되니 조건이 성립하면 벗어나기
				}
			}
			if( bl == false ) {
				cnt ++; //bl의 값이 false일 때 카운트를 1증가
			} //만약 true면 나머지가 서로 같다는 뜻이니 카운트를 올릴 필요x
		}
		System.out.println(cnt);
	}
}

Scanner는 코드짜기는 쉽지만(?) 정규식을 많이 쓴다고 해서 시간이 조금 느리다.

- 방법 2

BufferedReader를 이용하여 풀기

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {
	public static void main(String[] args) throws NumberFormatException, IOException {

		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

		int[] arr = new int[10];
		boolean bl; //n번째와 n+1번째랑 비교하기 위한 변수
		int cnt = 0; //서로 다른 나머지들의 개수를 측정하기 위한 변수

		for(int i=0; i<arr.length; i++ ) {
			arr[i] = Integer.parseInt(br.readLine()) % 42;
		}
		for(int i=0; i<10; i++ ) {
			bl = false; //기본값을 false로 설정
			for(int k=i+1; k<arr.length; k++ ) {
				if( arr[i] == arr[k] ) { //배열의 n번째와 n+1번째의 값을 비교
					bl = true; //같다면 bl값을 true로 변경
					break; //한번만 비교하면 되니 조건이 성립하면 벗어나기
				}
			}
			if( bl == false ) {
				cnt++; //bl의 값이 거짓일 때 카운트를 1증가
			} //만약 true면 나머지가 서로 같다는 뜻이니 카운트를 올릴 필요x
		}
		System.out.println(cnt);
	}
}

BufferedReader는 Buffer를 통해 입력받은 문자를 쌓아둔 뒤 문자열처럼 보내버린다.
대충 이래서 Scanner보다는 빠르다는 것만 알고있고 알고리즘 문제를 풀때 자주 쓰인다고 하니 외워두자.

백준에서 단계별로 풀어보기를 통해 문제를 풀어보았다면 'for문' 항목에 '빠른 A+B' 에서BufferedReader에 대해 나온다.
Scanner와 BufferedReader의 차이, 그리고 어떻게 쓰는지를 알고싶다면
JAVA [자바] - 입력 뜯어보기 [Scanner, InputStream, BufferedReader] < 여기에서 보면 좋겠다. 그리고 이 블로그에 JAVA - 백준 모음집을 보면 단계별로 문제풀이를 알려준다. 내가 알고리즘 문제를 풀때 많은 도움을 받았던 곳이다.

- 방법 3

BufferedReader, HashSet을 이용하여 풀기

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashSet;
 
public class Main {
	public static void main(String[] args) throws IOException {
		
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		HashSet<Integer> hs = new HashSet<Integer>();
 
		for (int i = 0; i < 10; i++) {
			hs.add(Integer.parseInt(br.readLine()) % 42);
		//입력받은 값의 나머지 값을 add메소드를 통해 HashSet에 저장
		}
		br.close();
		System.out.print(hs.size()); //HashSet의 값 출력
	}
}

HashSet은 Collection중 Set의 파생클래스로, 몇가지 특징이 있다.

  • 중복되는 원소를 넣을 경우 하나만 저장한다.(중복원소를 허용하지 않는다.)
  • HashSet은 순서 개념이 없어서 정렬하는 기능인 Collection.sort()메소드를 사용할 수 없다.
    (정렬하고 싶다면 리스트로 변환 후 정렬해야 한다.)
  • HashSet을 사용할 때는 배열을 사용하지 못하는 것으로 보인다.(뇌피셜)

처음에 두시간동안 문제를 고민했을 때 어떻게 검색하는지 몰라서 다시 문제를 읽어보았더니 '서로 다른 나머지의 갯수를 구하라'라는 부분이 '중복된 부분을 제거'라는 뜻으로 보여서 이 키워드로 검색을 했다.(문제를 잘 읽자.)

실무에서는 써야되는, 언젠가는 써야하는 상황이 생길 수 있기 때문에 알아두자.



제출 번호 : 29435049 - Scanner + HashSet
제출 번호 : 29434804 - BufferedReader + HashSet
제출 번호 : 29434755 - BufferedReader + 배열
제출 번호 : 29434750 - Scanner + 배열

BufferedReader + 배열을 쓰는 것이 메모리와 시간을 아낄수 있어서 성능은 좋은것 같다.
코드길이는 주석을 제거하면 조금 줄어들지도 모르겠다.

profile
천천히 그리고 꾸준히

3개의 댓글

comment-user-thumbnail
2021년 5월 20일

많은 도움이 됐습니다

1개의 답글
comment-user-thumbnail
2022년 12월 25일

잘보고 갑니다~

답글 달기